深入浅出之vue(原生实现变化监听)

51 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

深入浅出之vue(原生实现变化监听)

Object的变化侦测

常见的侦测变量变化的方法有Object.definePropertyES6的Proxy

Object.defineProperty

Object.defineProperty()的作用就是直接在一个对象上定义一个新属性,或者修改一个已经存在的属性

Object.defineProperty(obj, prop, desc)
  1. obj 需要定义属性的当前对象
  2. prop 当前需要定义的属性名
  3. desc 属性描述符

一般通过为对象的属性赋值的情况下,对象的属性可以修改也可以删除,但是通过Object.defineProperty()定义属性,通过描述符的设置可以进行更精准的控制对象属性

属性描述符(desc)

通过Object.defineProperty()为对象定义属性,有两种形式,且不能混合使用,分别为数据描述符(value,writable),存取描述符(getter,setter函数)

数据描述符

let Person = {}
Object.defineProperty(Person, 'name', {
   value: 'jack',
   writable: true // 是否可以改变
})

存取描述符

let Person = {}
let temp = null
Object.defineProperty(Person, 'name', {
  get: function () {
    return temp
  },
  set: function (val) {
    temp = val
  }
})

在这里插入图片描述

  1. configrable 描述属性是否配置,以及可否删除
  2. enumerable 描述属性是否会出现在for in 或者 Object.keys()的遍历中

configrable

在这里插入图片描述

  • configurable: false 时,不能删除当前属性,且不能重新配置当前属性的描述符(有一个小小的意外:可以把writable的状态由true改为false,但是无法由false改为true),但是在writable: true的情况下,可以改变value的值
  • configurable: true时,可以删除当前属性,可以配置当前属性所有描述符。

enumerable

在这里插入图片描述

ES6的Proxy

待定

通过Object.defineProperty实现vue监听变量

<template>
<h1>{{name}}</h1>
</template>

模板中使用了name,当其发送变化则需要通知所有使用他的地方. 所以最直接明了的方法就是先收集所有使用了name的依赖,当其属性发生了变化就遍历通知.总结起来,其实就一句话,在getter中收集依赖,在setter中触发依赖。