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 相关文章推荐
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
Apr 13 Javascript
JS构建页面的DOM节点结构的实现代码
Dec 09 Javascript
在百度知道团队中快速审批新成员的js脚本
Feb 02 Javascript
JS动态增加删除UL节点LI及相关内容示例
May 21 Javascript
教你在heroku云平台上部署Node.js应用
Jul 30 Javascript
Javascript实现的SHA-256加密算法完整实例
Feb 02 Javascript
JS加载iFrame出现空白问题的解决办法
May 13 Javascript
Vue实例中生命周期created和mounted的区别详解
Aug 25 Javascript
JavaScript实现开关等效果
Sep 08 Javascript
javascript回调函数详解
Feb 06 Javascript
解决vue组件中click事件失效的问题
Nov 09 Javascript
vue项目中微信登录的实现操作
Sep 08 Javascript
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
php-accelerator网站加速PHP缓冲的方法
2008/07/30 PHP
php 学习资料零碎东西
2010/12/04 PHP
php用正则表达式匹配URL的简单方法
2013/11/12 PHP
php获得刚插入数据的id 的几种方法总结
2018/05/31 PHP
Javascript中eval函数的使用方法与示例
2007/04/09 Javascript
Add a Table to a Word Document
2007/06/15 Javascript
WEB高性能开发之疯狂的HTML压缩
2010/06/19 Javascript
解决json日期格式问题的3种方法
2014/02/02 Javascript
JavaScript中的函数重载深入理解
2014/08/04 Javascript
JavaScript监听和禁用浏览器回车事件实例
2015/01/31 Javascript
AngularJS入门教程之更多模板详解
2016/08/19 Javascript
jQuery的三种bind/One/Live/On事件绑定使用方法
2017/02/23 Javascript
利用angularjs1.4制作的简易滑动门效果
2017/02/28 Javascript
Map.vue基于百度地图组件重构笔记分享
2017/04/17 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
2018/10/24 Javascript
详解Node.js amqplib 连接 Rabbit MQ最佳实践
2019/01/24 Javascript
详解微信小程序动画Animation执行过程
2020/09/23 Javascript
[56:17]NB vs Infamous 2019国际邀请赛淘汰赛 败者组 BO3 第三场 8.22
2019/09/05 DOTA
Python中使用Beautiful Soup库的超详细教程
2015/04/30 Python
使用50行Python代码从零开始实现一个AI平衡小游戏
2018/11/21 Python
对python numpy.array插入一行或一列的方法详解
2019/01/29 Python
python使用正则表达式(Regular Expression)方法超详细
2019/12/30 Python
Python绘制动态水球图过程详解
2020/06/03 Python
HTML里显示pdf、word、xls、ppt的方法示例
2020/04/14 HTML / CSS
Move Free官方海外旗舰店:美国骨关节健康专业品牌
2017/12/06 全球购物
阿迪达斯香港官网:adidas香港
2019/11/09 全球购物
电子商务个人职业生涯规划范文
2014/02/12 职场文书
住房租房协议书
2014/08/20 职场文书
幼儿园迎国庆65周年活动策划方案
2014/09/16 职场文书
就业协议书盖章的注意事项
2014/09/28 职场文书
个人师德师风自我剖析材料
2014/09/29 职场文书
公安领导班子四风问题个人整改措施思想汇报
2014/10/09 职场文书
《少年闰土》教学反思
2016/02/18 职场文书
你对自己的信用报告有过了解吗?
2019/07/09 职场文书
Nginx防盗链与服务优化配置的全过程
2022/01/18 Servers
「天才王子的赤字国家重生术」妮妮姆·拉雷粘土人开订
2022/03/21 日漫