Vue.js 是一款 MVVM 框架,数据模型仅仅是普通的 JavaScript 对象,但是对这些对象进行操作时,却能影响对应视图,它的核心实现就是「响应式系统」。
首先我们定义一个cb函数,这个函数用来模拟视图更新,调用它即代表更新视图。
function cb (newVal) {
console.log('视图更新了 ==> ' + newVal);
}
然后我们定义一个defineReactive,这个方法通过Object.defineProperty来实现对对像的响应式话, 入参是一个obj(需要绑定的对象)、key(obj的某一个属性),val(具体的值)。经过defineReactive处理以后,我们obj的key属性在读的时候会触发reactiveGetter方法,而在该属性被写的时候则会触发reactiveSetter方法。
function defineReactive (obj, key, val) {
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
return val;
},
set: function reactiveSetter (newVal) {
if (newVal === val) {
return;
}
cb(newVal);
}
});
}
当然这是不够的,我们需要在上面再封装一层observer。这个函数传入一个value(需要响应式的对象),通过遍历所有属性的方式对该对象的每一个属性都通过defineReactive处理。
function observer (value) {
if (!value || !(typeof value !== 'object')) {
return;
}
Object.keys(value).forEach((key) => {
defineReactive(value, key, value[key]);
});
}
最后,封装一个Vue
class Vue {
constructor (options) {
this._data = options.data;
observer(this._data);
}
}
这样我们只要new一个Vue对象,就会将data中的数据进行响应式化。我们对data的属性进行下面的操作,就会触发cb方法更新视图。
let o = new Vue({
data: {
test: 'I am test~'
}
});
o._data.test = 'Hello,world~';