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 相关文章推荐
jquery tablesorter.js 支持中文表格排序改进
Dec 09 Javascript
JavaScript全局函数使用简单说明
Mar 11 Javascript
jquery模拟按下回车实现代码
Sep 20 Javascript
Ionic快速安装教程
Jun 03 Javascript
详解vue.js组件化开发实践
Dec 14 Javascript
TableSort.js表格排序插件使用方法详解
Feb 10 Javascript
详解webpack自定义loader初探
Aug 29 Javascript
js中获取URL参数的共用方法getRequest()方法实例详解
Oct 24 Javascript
node.js的http.createServer过程深入解析
Jun 06 Javascript
Bootstrap实现模态框效果
Sep 30 Javascript
详解小程序BackgroundAudioManager踩坑之旅
Dec 08 Javascript
linux服务器快速卸载安装node环境(简单上手)
Feb 22 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学习笔记 数组遍历实现代码
2011/06/09 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
2015/09/29 PHP
PHP发送AT指令实例代码
2016/05/26 PHP
php可变长参数处理函数详解
2017/02/22 PHP
ThinkPHP实现分页功能
2017/04/28 PHP
一个很简单的jquery+xml+ajax的无刷新树结构(无css,后台是c#)
2010/06/02 Javascript
不提示直接关闭网页窗口的JS示例代码
2013/12/17 Javascript
js与jquery获取父级元素,子级元素,兄弟元素的实现方法
2014/01/09 Javascript
实例讲解JQuery中this和$(this)区别
2014/12/08 Javascript
对象题目的一个坑 理解Javascript对象
2015/12/22 Javascript
jQuery插件ajaxFileUpload异步上传文件
2016/10/19 Javascript
jQuery实现动态给table赋值的方法示例
2017/07/04 jQuery
简单实现js鼠标跟随效果
2020/08/02 Javascript
详解axios 全攻略之基本介绍与使用(GET 与 POST)
2017/09/15 Javascript
微信小程序实现聊天对话(文本、图片)功能
2018/07/06 Javascript
用VueJS写一个Chrome浏览器插件的实现方法
2019/02/27 Javascript
用 js 写一个 js 解释器过程详解
2019/08/02 Javascript
vue使用i18n实现国际化的方法详解
2019/09/05 Javascript
详解webpack打包vue项目之后生成的dist文件该怎么启动运行
2019/09/06 Javascript
[14:36]2014 DOTA2国际邀请赛中国区预选赛5.21 Orenda VS NE
2014/05/22 DOTA
urllib2自定义opener详解
2014/02/07 Python
如何高效使用Python字典的方法详解
2017/08/31 Python
python pandas获取csv指定行 列的操作方法
2019/07/12 Python
Python合并2个字典成1个新字典的方法(9种)
2019/12/19 Python
如何基于python3和Vue实现AES数据加密
2020/03/27 Python
Python如何在循环内使用list.remove()
2020/06/01 Python
amazeui模态框弹出后立马消失并刷新页面
2020/08/19 HTML / CSS
自荐信的禁忌和要点
2013/10/15 职场文书
工厂门卫岗位职责
2013/11/25 职场文书
计算机应用应届生求职信
2014/07/12 职场文书
党的群众路线教育实践活动组织生活会发言材料
2014/10/17 职场文书
12.4全国法制宣传日活动方案
2014/11/02 职场文书
律师函格式范本
2015/05/27 职场文书
Vue实现动态查询规则生成组件
2021/05/27 Vue.js
oracle索引总结
2021/09/25 Oracle
vue实现Toast组件轻提示
2022/04/10 Vue.js