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 12 Javascript
JQuery优缺点分析说明
Apr 10 Javascript
Jquery操作下拉框(DropDownList)实现取值赋值
Aug 13 Javascript
常用jQuery选择器总结
Jul 11 Javascript
JavaScript中用sort()方法对数组元素进行排序的操作
Jun 09 Javascript
实现高性能JavaScript之执行与加载
Jan 30 Javascript
分享JS代码实现鼠标放在输入框上输入框和图片同时更换样式
Sep 01 Javascript
jQuery与js实现颜色渐变的方法
Dec 30 Javascript
Node.js使用Express.Router的方法
Nov 14 Javascript
JavaScript中Array方法你该知道的正确打开方法
Sep 11 Javascript
浅谈JavaScript 代码简洁之道
Jan 09 Javascript
微信小程序webview 脚手架使用详解
Jul 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合并数组array_merge函数运算符加号与的区别
2008/10/31 PHP
thinkPHP模板算术运算相关函数用法分析
2016/07/12 PHP
Laravel框架实现model层的增删改查(CURD)操作示例
2018/05/12 PHP
JavaScript window.location对象
2014/11/14 Javascript
使用原生JS实现弹出层特效
2014/12/22 Javascript
jQuery找出网页上最高元素的方法
2015/03/20 Javascript
JavaScript中字符串分割函数split用法实例
2015/04/07 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
2015/12/13 Javascript
jQuery Mobile中的button按钮组件基础使用教程
2016/05/23 Javascript
基于angular中的重要指令详解($eval,$parse和$compile)
2016/10/21 Javascript
EasyUi 打开对话框后控件赋值及赋值后不显示的问题解决办法
2017/01/19 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
详解VUE中的插值( Interpolation)语法
2020/10/18 Javascript
JS实现多功能计算器
2020/10/28 Javascript
win7 下搭建sublime的python开发环境的配置方法
2014/06/18 Python
整理Python 常用string函数(收藏)
2016/05/30 Python
python使用threading获取线程函数返回值的实现方法
2017/11/15 Python
Python+matplotlib+numpy绘制精美的条形统计图
2018/01/02 Python
面向初学者的Python编辑器Mu
2018/10/08 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
2019/04/16 Python
Python静态类型检查新工具之pyright 使用指南
2019/04/26 Python
python制作填词游戏步骤详解
2019/05/05 Python
selenium+Chrome滑动验证码破解二(某某网站)
2019/12/17 Python
Django中的session用法详解
2020/03/09 Python
Python搭建Keras CNN模型破解网站验证码的实现
2020/04/07 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
HTML5中input输入框默认提示文字向左向右移动的示例代码
2020/09/10 HTML / CSS
中国跨境电子商务网站:NewFrog
2018/03/10 全球购物
个人函授自我鉴定
2014/03/25 职场文书
经管应届生求职信范文
2014/05/18 职场文书
技能比武方案
2014/05/21 职场文书
党员个人对照检查材料范文
2014/09/24 职场文书
四风问题自我剖析材料
2014/10/07 职场文书
2015年计生协会工作总结
2015/04/24 职场文书
小学家长意见怎么写
2015/06/03 职场文书
gojs实现蚂蚁线动画效果
2022/02/18 Javascript