007_重学Vue_数据代理

185 阅读2分钟

Vue 2 数据代理实现方式

数据代理是指通过一个对象代理另一个对象属性的读写操作。Vue 2 通过 Object.defineProperty 实现数据代理。defineProperty 方法有3个参数。

  1. 第一个参数是要定义属性的对象;
  2. 第二个参数是要定义属性的key;
  3. 第三个参数是一个配置项;
const person = { name: 'allen', sex: '男' }

Object.defineProperty(person, 'age', {
  value: 18, //设置的值;
  enumerable: true, //是否可以枚举,默认为flase。值为false时 Object.keys(obj) 不包含定义的 key;
  writable: true, //是否可写,默认为false。值为 false 时不可修改age的值;
  configurable: true, //默认为false。当值为false时 delete person.age 删除不成功,返回false;
})

配置项还包含getset两个方法,取值时调用 get 方法,设置值时调用 set 方法。

const person = { name: 'allen', sex: '男' }
let num = 10;

Object.defineProperty(person, 'age', {
  //get有多种写法
  //1、get: function getAge()
  //2、get: function()
  //3、get()
  get() {
    return num;
  },
  set(val) {
    num = val;
  }
})

响应式原理

数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。

追踪变化

Vue 将遍历data所有的 property,并使用 Object.defineProperty 把这些 property 全部转为 getter/setterObject.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。

  1. 每个组件实例都对应一个 watcher 实例。
  2. 在组件渲染的过程中 watcher 把“接触”过的数据 property 记录为依赖。
  3. 之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

image.png

image.png

Vue 实例 vm 中包含_data属性,这个 _data 就是配置项中的data,模板中可以通过 {{_data.xxx}} 访问 data 中的属性。为了方便使用, Vue 通过 Object.defineProperty 把data上的所有属性都加到 vm 实例上。这样就可以直接使用 {{xxx}}