Vue源码学习(4)——数据响应系统:通过initData() 看数据响应系统
下面,根据理解我们写一个简略的源码:参考
治愈watcher在:vm.$mount(vm.$options.el)
Function defineReactive(obj,key,val){
Object.defineProperty(obj,key, {
enumerable: true,
configurable: true,
get: function () {
if (Dep. Target ) {
dep. Depend (); //收集依赖等同 dep.addSub(Dep.target)
}
return val;
},
set: function (newVal) {
//判断新值与旧值是否相等,判断的后半段是为了验证新值与旧值都为NaN的情况,NaN不等于自身
if (newVal === val || (newVal !== newVal && value !== value)){
return ;
}
val = newVal;
dep. notify (); //发布改变
}
});
}
class Dep {
constructor(){
this.subs = []; //订阅的信息
}
addSub(sub){
this.subs.push(sub);
}
removeSub (sub) {
remove(this.subs, sub);
}
depend() { //此方法的作用等同于 this.subs.push(Watcher);
if (Dep.target) {
Dep.target.addDep(this);
}
}
notify () {//这个方法就是发布通知了 告诉你 有改变啦
const subs = this.subs.slice()
for (let i = 0, l = subs.length; i < l; i++) { subs[i].update(); }
}
}
Dep.target = null;
//低配的不能再低配的watcher对象
//(源码中是一个类,这用一个对象代替)
const watcher = {
addDep:function (dep) {
dep. addSub(this);
},
update: function() {
html();
}
}
//假装这个是渲染页面的
function html () {
document.querySelector('body')
.innerHTML = obj.html;
}
defineReactive(obj,'html','how are you');//定义响应式的数据
Dep.target = watcher;
html();//第一次渲染界面
Dep.target = null;
/*
浏览器测试:
首先,网页内容为:'how are you'
然后,在控制台输入:
obj.html = 'I am fine thank you'
网页内容变为:'I am fine thank you'
*/