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限制textarea每行输入字符串长度的代码
Oct 31 Javascript
javascript阻止浏览器后退事件防止误操作清空表单
Nov 22 Javascript
JSONP和批量操作功能的实现方法
Aug 21 Javascript
jQuery下拉菜单的实现代码
Nov 03 Javascript
jquery实现input框获取焦点的简单实例
Jan 26 Javascript
Nuxt.js实战详解
Jan 18 Javascript
JS实现为动态创建的元素添加事件操作示例
Mar 17 Javascript
js中如何完美的解析数据
Mar 18 Javascript
Vue extend的基本用法(实例详解)
Dec 09 Javascript
详解Vue 单文件组件的三种写法
Feb 19 Javascript
JavaScript前端开发时数值运算的小技巧
Jul 28 Javascript
React中使用Vditor自定义图片详解
Dec 25 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
百度站点地图(百度sitemap)生成方法分享
2014/01/09 PHP
php项目开发中用到的快速排序算法分析
2016/06/25 PHP
thinkphp自定义权限管理之名称判断方法
2017/04/01 PHP
利用PHP获取汉字首字母并且分组排序详解
2017/10/22 PHP
php基于Redis消息队列实现的消息推送的方法
2018/11/28 PHP
在IE模态窗口中自由查看HTML源码的方法
2007/03/08 Javascript
用JavaScript实现类似于ListBox功能示例代码
2014/03/09 Javascript
jQuery响应鼠标事件并隐藏与显示input默认值
2014/08/24 Javascript
JS回调函数的应用简单实例
2014/09/17 Javascript
JavaScript实现函数返回多个值的方法
2015/06/09 Javascript
九种原生js动画效果
2015/11/11 Javascript
如何判断出一个js对象是否一个dom对象
2016/11/24 Javascript
在js代码拼接dom对象到页面上去的模板总结(必看)
2017/02/14 Javascript
vue中阻止click事件冒泡,防止触发另一个事件的方法
2018/02/08 Javascript
JS常见DOM节点操作示例【创建 ,插入,删除,复制,查找】
2018/05/14 Javascript
nodejs 使用 js 模块的方法实例详解
2018/12/04 NodeJs
从0到1学习JavaScript编写贪吃蛇游戏
2020/07/28 Javascript
vue-以文件流-blob-的形式-下载-导出文件操作
2020/08/07 Javascript
如何HttpServletRequest文件对象并储存
2020/08/14 Javascript
JavaScript实现点击出现子菜单效果
2021/02/08 Javascript
python单链表实现代码实例
2013/11/21 Python
python正则表达式re模块详细介绍
2014/05/29 Python
python中的字典使用分享
2016/07/31 Python
python中的set实现不重复的排序原理
2018/01/24 Python
Python实现确认字符串是否包含指定字符串的实例
2018/05/02 Python
对python 中class与变量的使用方法详解
2019/06/26 Python
基于python的Paxos算法实现
2019/07/03 Python
美国家用电器和电子产品商店:Abt
2016/09/06 全球购物
拥有超过850家商店的美国在线派对商店:Party City
2018/10/21 全球购物
New Balance俄罗斯官方网上商店:购买运动鞋
2020/03/02 全球购物
ShellScript面试题一则-ShellScript编程
2014/06/24 面试题
工商管理实习生自我鉴定范文
2013/12/18 职场文书
党的群众路线教育实践活动总结大会主持词
2014/10/30 职场文书
2015年事业单位办公室文员工作总结
2015/04/24 职场文书
筑梦中国心得体会
2016/01/18 职场文书
Python干货实战之八音符酱小游戏全过程详解
2021/10/24 Python