Vue数据驱动模拟实现2
一、前言在随笔“”结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗? 如下: 倘若user中的name、age属性变化,如何知道它们变化了呢? 今儿,就来解决这一问题。 通过走读Vue源码,发现他是利用Observer构造函数为每个对象创建一个Observer对象,来监听数据的,如果数据中的属性又是一个对象,那么就又通过Observer来监听嘛。 其实,核心思想就是树的先序遍历(关于树,可参考here)。如我们将上述Demo中的data数据,图形化一下,就更加明白了,如下: 好了,理清了大体思路,下面我们就一起来创建一个Observer吧。 二、Observer构造Observer整体结构如下: let p = Observer.prototype = Object.create(null);
p.walk = function(data){ p.convert = function(key,val){ 好了,下面,我们一起来完成walk以及convert方法吧。 -walk- 首先,我们在walk方法中实现对data对象中的所有属性监听,如下: {
let val = data[key];
this.convert(key,val);
});
}
且,由于属性中可能又会是一个对象,那么,我们就有必要监听它们。 怎么办呢?如果是个对象,再次利用Observer构造函数,处理它不就完了么。 如下: {
let val = data[key];
//如果val为对象,则交给Observer处理
if(typeof val === 'object'){
Observer(val);
}
this.convert(key,val);
});
}
你可能会有这样的疑问,如果直接利用Observer处理对象,那么不就与父对象失去关联了么? 然而并没有,因为JavaScript对于对象是指向地址关系,所以怎么会失去关联呢。 -convert- 对于convert方法,就比较简单了,一如既往就是利用Object.defineProperty监听数据,如下: {
console.log('访问了'+key+' 值为'+val);
return val;
},set: (newVal)=>{
console.log('设置了'+key+' 值为'+newVal);
if(newVal !== val){
val = newVal;
}
}
});
}
好了,到此,一个简单的Observer就构造完成,下面我们就来测试下,是否成功监听了每个属性。 效果如下: Perfect,完整代码见。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |