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 相关文章推荐
JS 控制非法字符的输入代码
Dec 04 Javascript
jQuery.extend()、jQuery.fn.extend()扩展方法示例详解
May 08 Javascript
JavaScript函数作用域链分析
Feb 13 Javascript
JavaScript继承模式粗探
Jan 12 Javascript
jQuery实现图片轮播效果代码
Sep 27 Javascript
整理一下常见的IE错误
Nov 18 Javascript
前端 Vue.js 和 MVVM 详细介绍
Dec 29 Javascript
使用vue打包时vendor文件过大或者是app.js文件很大的问题
Jun 29 Javascript
vue中多个倒计时实现代码实例
Mar 27 Javascript
es6中reduce的基本使用方法
Sep 10 Javascript
《javascript设计模式》学习笔记三:Javascript面向对象程序设计单例模式原理与实现方法分析
Apr 07 Javascript
Vue使用Three.js加载glTF模型的方法详解
Jun 14 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&amp;&amp;mysql)四
2006/10/09 PHP
php 图片加水印与上传图片加水印php类
2010/05/12 PHP
php中文乱码怎么办如何让浏览器自动识别utf-8
2014/01/15 PHP
php如何修改SESSION的生存存储时间的实例代码
2017/07/05 PHP
jQuery实现的立体文字渐变效果
2010/05/17 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
2016/07/21 Javascript
JavaScript实现图片懒加载(Lazyload)
2016/11/28 Javascript
jQuery命名空间与闭包用法示例
2017/01/12 Javascript
js自定义Tab选项卡效果
2017/06/05 Javascript
详解Angular 自定义结构指令
2017/06/21 Javascript
Bootstrap Multiselect 常用组件实现代码
2017/07/09 Javascript
基于nodejs+express4.X实现文件下载的实例代码
2017/07/13 NodeJs
详解vue.js之绑定class和style的示例代码
2017/08/24 Javascript
基于 Vue.js 之 iView UI 框架非工程化实践记录(推荐)
2017/11/21 Javascript
JS笛卡尔积算法与多重数组笛卡尔积实现方法示例
2017/12/01 Javascript
关于element-ui的隐藏组件el-scrollbar的使用
2019/05/29 Javascript
Vue实现图片与文字混输效果
2019/12/04 Javascript
Vue 请求传公共参数的操作
2020/07/31 Javascript
Python自定义函数的创建、调用和函数的参数详解
2014/03/11 Python
Python实现的读取电脑硬件信息功能示例
2018/05/30 Python
使用pycharm设置控制台不换行的操作方法
2019/01/19 Python
python 多线程串行和并行的实例
2019/02/22 Python
python用什么编辑器进行项目开发
2020/06/17 Python
Python读取xlsx数据生成图标代码实例
2020/08/12 Python
用CSS3打造HTML5的Logo(实现代码)
2016/06/16 HTML / CSS
Monnier Frères美国官网:法国知名奢侈品网站
2016/11/22 全球购物
Mio Skincare法国官网:身体紧致及孕期身体护理
2018/04/04 全球购物
美国农场鲜花速递:The Bouqs
2018/07/13 全球购物
介绍一下Java的安全机制
2012/06/28 面试题
施工协议书范本
2014/04/22 职场文书
应届毕业生自荐书
2014/06/18 职场文书
民主生活会对照检查材料范文
2014/10/01 职场文书
典型事迹材料范文
2014/12/29 职场文书
委托书英文
2015/01/28 职场文书
为什么node.js不适合大型项目
2021/04/28 Javascript
千万级用户系统SQL调优实战分享
2022/03/03 MySQL