- Vue.js基于
Object.defineProperty
实现 响应式系统
1 Object.defineProperty
/*
* obj: 目标对象
* prop: 需要操作的目标对象的属性名
* descriptor: 描述符
* return value 传入对象
*/
Object.defineProperty(obj, prop, descriptor)
descriptor 的属性
enumberable
: 属性是否可枚举,默认 falseconfigurable
: 属性是否可被修改|删除,默认 falseget
: 获取属性的方法set
: 设置属性的方法
2 实现 observer(可观察的)
1. 定义函数 cb
:模拟视图更新,调用 cb 即代表更新视图
function cb (val) {
// 渲染视图
console.log('视图更新啦~');
}
2. 定义 defineReactive
函数:通过 Object.defineProperty
来实现对对象的响应式化
入参:obj(需要绑定的对象)、key(obj的某一个属性)、val(具体的值)
经过
defineReactive
处理后,我们的 obj 的 key 属性在 读 时会触发reactiveGetter
方法,而在该属性被 写 时会触发reactiveSetter
方法
function defineReactive (obj, key, val) {
Object.defineProperty(obj, key, {
enumberable: true,
configurable: true,
get: function reactiveGetter () {
return val; // 实际上会收集依赖
},
set: function reactiveSetter (newVal) {
if (newVal === val) return;
val = newVal;
cb(newVal);
}
})
}
3. 封装一层 observer
:传入一个 value
(需要响应式化的对象),通过遍历所有属性的方式对该对象的每一个属性都通过 defineReactive
处理
实际上 Observer 会进行递归调用
function observer (value) {
if(!value || (typeof value !== 'object')) {
return;
}
Object.keys(value).forEach(key => {
defineReactive(value, key, value[key]);
});
}
3 封装 Vue
1. 在 Vue 的构造函数中,对 options 的 data 进行处理,这里的 data 就是 Vue 实例中的 data 属性
data 实际上是一个属性,这里当作一个对象简单处理
class Vue {
// Vue构造类
constructor (options) {
this._data = options.data;
observer(this._data);
}
}
2. new 一个 Vue 对象时,就会将 data 中的数据进行响应式化
改变 data 属性值,就会触发
cb
方法更新视图
let o = new Vue({
data: {
test: 'I am test.'
}
});
o._data.test = 'Hello world'; // 视图更新啦~