Vue 2 数据代理实现方式
数据代理是指通过一个对象代理另一个对象属性的读写操作。Vue 2 通过 Object.defineProperty 实现数据代理。defineProperty 方法有3个参数。
- 第一个参数是要定义属性的对象;
- 第二个参数是要定义属性的key;
- 第三个参数是一个配置项;
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;
})
配置项还包含get和set两个方法,取值时调用 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/setter。Object.defineProperty 是 ES5 中一个无法 shim 的特性,这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
- 每个组件实例都对应一个 watcher 实例。
- 在组件渲染的过程中 watcher 把“接触”过的数据 property 记录为依赖。
- 之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。
Vue 实例 vm 中包含_data属性,这个 _data 就是配置项中的data,模板中可以通过 {{_data.xxx}} 访问 data 中的属性。为了方便使用, Vue 通过 Object.defineProperty 把data上的所有属性都加到 vm 实例上。这样就可以直接使用 {{xxx}}。