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 相关文章推荐
List Information About the Binary Files Used by an Application
Jun 11 Javascript
ExtJS GridPanel 根据条件改变字体颜色
Mar 08 Javascript
类似天猫商品详情随浏览器移动的示例代码
Feb 27 Javascript
特殊情况下如何获取span里面的值
May 20 Javascript
jQuery同步提交示例代码
Dec 12 Javascript
js实现input密码框提示信息的方法(附html5实现方法)
Jan 14 Javascript
火狐和ie下获取javascript 获取event的方法(推荐)
Nov 26 Javascript
jQuery动态生成表格及右键菜单功能示例
Jan 13 Javascript
angular.js4使用 RxJS 处理多个 Http 请求
Sep 23 Javascript
微信小程序loading组件显示载入动画用法示例【附源码下载】
Dec 09 Javascript
原生JS forEach()和map()遍历的区别、兼容写法及jQuery $.each、$.map遍历操作
Feb 27 jQuery
Vue实现导入Excel功能步骤详解
Jul 03 Vue.js
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中对于浮点型的数据需要用不同的方法解决
2014/03/11 PHP
PHP常用文件操作函数和简单实例分析
2016/06/03 PHP
完美的php分页类
2017/10/24 PHP
javascript读取xml
2006/11/04 Javascript
Javascript与flash交互通信基础教程
2008/08/07 Javascript
一句话JavaScript表单验证代码
2009/08/02 Javascript
兼容多浏览器的iframe自适应高度(ie8 、谷歌浏览器4.0和 firefox3.5.3)
2009/11/04 Javascript
封装的原生javascript弹出层代码
2010/09/24 Javascript
一个奇葩的最短的 IE 版本判断JS脚本
2014/05/28 Javascript
jqTransform美化表单
2015/10/10 Javascript
jquery可定制的在线UEditor编辑器
2015/11/17 Javascript
Angularjs整合微信UI(weui)
2016/03/15 Javascript
jquery实现全选和全不选功能效果的实现代码【推荐】
2016/05/05 Javascript
Javascript实现base64的加密解密方法示例
2017/06/27 Javascript
JS实现获取汉字首字母拼音、全拼音及混拼音的方法
2017/11/14 Javascript
Python实现获取域名所用服务器的真实IP
2015/10/25 Python
Python各类图像库的图片读写方式总结(推荐)
2018/02/23 Python
Python基于更相减损术实现求解最大公约数的方法
2018/04/04 Python
Python绘制并保存指定大小图像的方法
2019/01/10 Python
详解Python Matplot中文显示完美解决方案
2019/03/07 Python
解决Django migrate不能发现app.models的表问题
2019/08/31 Python
python实现横向拼接图片
2020/03/23 Python
Django bulk_create()、update()与数据库事务的效率对比分析
2020/05/15 Python
Python Selenium XPath根据文本内容查找元素的方法
2020/12/07 Python
eDreams德国:南欧领先的在线旅游公司
2020/12/07 全球购物
如何利用cmp命令比较文件
2016/04/11 面试题
轻金属冶金专业毕业生自荐信
2013/11/02 职场文书
七匹狼男装广告词
2014/03/21 职场文书
技校毕业生自荐信
2014/06/03 职场文书
2014年创卫工作总结
2014/11/24 职场文书
女性健康知识讲座主持词
2015/07/04 职场文书
2015年终个人政治思想工作总结
2015/11/24 职场文书
2019通用版新员工入职培训方案!
2019/07/11 职场文书
Python Matplotlib绘制动画的代码详解
2022/05/30 Python
vue ant design 封装弹窗表单的使用
2022/06/01 Vue.js
python如何读取和存储dict()与.json格式文件
2022/06/25 Python