最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 科技 - 知识百科 - 正文

Vue数据驱动模拟实现2

来源:动视网 责编:小采 时间:2020-11-27 20:26:37
文档

Vue数据驱动模拟实现2

Vue数据驱动模拟实现2:一、前言在随笔模拟Vue之数据驱动1结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗?如下:倘若user中的name、age属性变化,如何知道它们变化了呢?今儿,就来解决这一问题。通过走读Vue源码,发现他是利用Ob
推荐度:
导读Vue数据驱动模拟实现2:一、前言在随笔模拟Vue之数据驱动1结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗?如下:倘若user中的name、age属性变化,如何知道它们变化了呢?今儿,就来解决这一问题。通过走读Vue源码,发现他是利用Ob
 一、前言

在随笔“模拟Vue之数据驱动1”结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗?

如下:

倘若user中的name、age属性变化,如何知道它们变化了呢?

今儿,就来解决这一问题。

通过走读Vue源码,发现他是利用Observer构造函数为每个对象创建一个Observer对象,来监听数据的,如果数据中的属性又是一个对象,那么就又通过Observer来监听嘛。

其实,核心思想就是树的先序遍历(关于树,可参考here)。如我们将上述Demo中的data数据,图形化一下,就更加明白了,如下:

好了,理清了大体思路,下面我们就一起来创建一个Observer吧。

二、Observer构造

Observer整体结构如下:

function Observer(data){
 //如若this不是Observer对象,即创建一个
 if(!(this instanceof Observer)){
 return new Observer(data);
 }
 this.data = data;
 this.walk(data);
}
 
let p = Observer.prototype = Object.create(null);
 
p.walk = function(data){
 /*
 TODO:监听data数据中的所有属性,
 并查看data中属性值是否为对象,
 若为对象,就创建一个Observer实例
 */
}
 
p.convert = function(key, val){
 //TODO:通过Object.defineProperty监听数据
}

好了,下面,我们一起来完成walk以及convert方法吧。

-walk-

首先,我们在walk方法中实现对data对象中的所有属性监听,如下:

p.walk = function(data){
 let keys = Object.keys(data);
 keys.forEach( key => {
 let val = data[key];
 this.convert(key, val);
 });
}

且,由于属性中可能又会是一个对象,那么,我们就有必要监听它们。

怎么办呢?

如果是个对象,再次利用Observer构造函数,处理它不就完了么。

如下:

p.walk = function(data){
 let keys = Object.keys(data);
 keys.forEach( key => {
 let val = data[key];
 //如果val为对象,则交给Observer处理
 if(typeof val === 'object'){
 Observer(val);
 }
 this.convert(key, val);
 });
}

你可能会有这样的疑问,如果直接利用Observer处理对象,那么不就与父对象失去关联了么?

然而并没有,因为JavaScript对于对象是指向地址关系,所以怎么会失去关联呢。

-convert-

对于convert方法,就比较简单了,一如既往就是利用Object.defineProperty监听数据,如下:

p.convert = function(key, val){
 Object.defineProperty(this.data, key, {
 get: ()=>{
 console.log('访问了'+key+' 值为'+val);
 return val;
 },
 set: (newVal)=>{
 console.log('设置了'+key+' 值为'+newVal);
 if(newVal !== val){
 val = newVal;
 }
 }
 });
}

好了,到此,一个简单的Observer就构造完成,下面我们就来测试下,是否成功监听了每个属性。

<script src="./observer.js"></script>
<script>
 let data = {
 user: {
 name: 'Monkey',
 age: 24
 },
 lover: {
 name: 'Dorie',
 age: 23
 }
 };
 Observer(data);
</script>

效果如下:

文档

Vue数据驱动模拟实现2

Vue数据驱动模拟实现2:一、前言在随笔模拟Vue之数据驱动1结尾处,我们说到如果监听的属性是个对象呢?那么这个对象中的其他属性岂不就是监听不了了吗?如下:倘若user中的name、age属性变化,如何知道它们变化了呢?今儿,就来解决这一问题。通过走读Vue源码,发现他是利用Ob
推荐度:
标签: 数据 VUE 实现
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top