Vue数据驱动模拟实现2


Posted in Javascript onJanuary 11, 2017

一、前言

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

如下:

 Vue数据驱动模拟实现2

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

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

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

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

Vue数据驱动模拟实现2 

好了,理清了大体思路,下面我们就一起来创建一个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

Perfect,完整代码见github。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
document.all与WEB标准
May 13 Javascript
推荐11款jQuery开发的复选框和单选框美化插件
Aug 02 Javascript
js对象关系图 方便dom操作
Mar 18 Javascript
5秒后跳转效果(setInterval/SetTimeOut)
May 03 Javascript
js实现数组去重、判断数组以及对象中的内容是否相同
Nov 29 Javascript
javascript 中that的含义示例介绍
May 14 Javascript
JS操作JSON方法总结(推荐)
Jun 14 Javascript
基于jQuery的AJAX和JSON实现纯html数据模板
Aug 09 Javascript
jQuery Form表单取值的方法
Jan 11 Javascript
JavaScript之Date_动力节点Java学院整理
Jun 28 Javascript
微信小程序云开发之使用云函数
May 17 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
May 30 jQuery
jQuery实现对象转为url参数的方法
Jan 11 #Javascript
将鼠标焦点定位到文本框最后(代码分享)
Jan 11 #Javascript
移动端界面的适配
Jan 11 #Javascript
bootstrapValidator bootstrap-select验证不可用的解决办法
Jan 11 #Javascript
HTML5 js实现拖拉上传文件功能
Nov 20 #Javascript
Bootstrap表单控件使用方法详解
Jan 11 #Javascript
老生常谈的跨域处理
Jan 11 #Javascript
You might like
杏林同学录(四)
2006/10/09 PHP
比较好用的PHP防注入漏洞过滤函数代码
2012/04/11 PHP
php获取$_POST同名参数数组的实现介绍
2013/06/30 PHP
ThinkPHP结合AjaxFileUploader实现无刷新文件上传的方法
2014/10/29 PHP
浅析PHP中call user func()函数及如何使用call user func调用自定义函数
2015/11/05 PHP
详解PHP执行定时任务的实现思路
2015/12/21 PHP
PHP用户管理中常用接口调用实例及解析(含源码)
2017/03/09 PHP
PHP封装的完整分页类示例
2018/08/21 PHP
js 图片缩放(按比例)控制代码
2009/05/27 Javascript
jquery 选择器部分整理
2009/10/28 Javascript
js重写alert控件(适合学习js的新手朋友)
2014/08/24 Javascript
JavaScript判断textarea值是否为空并给出相应提示
2014/09/04 Javascript
JavaScript实现生成GUID(全局统一标识符)
2014/09/05 Javascript
14个有用的Jquery技巧分享
2015/01/08 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
2015/01/13 Javascript
nodejs通过phantomjs实现下载网页
2015/05/04 NodeJs
JavaScript实现的背景自动变色代码
2015/10/17 Javascript
AngularJS中的缓存使用
2017/01/11 Javascript
EasyUI的TreeGrid的过滤功能的解决思路
2017/08/08 Javascript
javascript数组定义的几种方法
2017/10/06 Javascript
JavaScript实现单图片上传并预览功能
2019/09/30 Javascript
vue解决跨域问题(推荐)
2020/11/10 Javascript
python发送邮件接收邮件示例分享
2014/01/21 Python
12步入门Python中的decorator装饰器使用方法
2016/06/20 Python
python爬虫爬取网页表格数据
2018/03/07 Python
Python实现定时备份mysql数据库并把备份数据库邮件发送
2018/03/08 Python
在mac下查找python包存放路径site-packages的实现方法
2018/11/06 Python
python输出带颜色字体实例方法
2019/09/01 Python
Python使用uuid库生成唯一标识ID
2020/02/12 Python
澳大利亚香水在线商店:City Perfume
2020/09/02 全球购物
大学生期末自我鉴定
2014/02/01 职场文书
计算机维护专业推荐信
2014/02/27 职场文书
事假请假条范文
2014/04/11 职场文书
2015年班长个人工作总结
2015/04/03 职场文书
2016年中秋节慰问信
2015/12/01 职场文书
2019年英语版感谢信(8篇)
2019/09/29 职场文书