Vue数据驱动模拟实现5


Posted in Javascript onJanuary 13, 2017

一、前言

在"模拟Vue之数据驱动4"中,我们实现了push、pop等数组变异方法。

但是,在随笔末尾我们提到,当pop、sort这些方法触发后,该怎么办呢?因为其实,它们并没有往数组中新增属性呢。

而且,当数据改动后,如果我们在变动数据处,就立即更改数据也未免性能不够,此时,走读Vue源码,发现他用了一个很巧妙的方法,就是职责链模式。当某个数据有所变动时,它会向上传递,通俗点就是冒泡至根结点,这样我们也可以在自己代码中使用事件代理咯,哇卡哇卡。

示意图如下所示:

Vue数据驱动模拟实现5

好了,说了这么多,我们下面就一起来实现下吧。

二、正文

注:以下代码皆编写在observer.js文件中。

首先,当数据变动,或者触发某个事件时,我们需要与变动数据关联一个自定义事件(自定义事件详情见here),如果触发某个事件,那么就执行,如下:

绑定事件方法:

//let p = Observer.prototype
p.on = function(eventName, fn){
 let listener = this.listener = this.listener || [];
 if(typeof eventName === 'string' && typeof fn === 'function'){
  if(!listener[eventName]){
   listener[eventName] = [fn];
  }else{
   listener[eventName].push(fn);
  }
 } 
}

取消事件方法:

//let p = Observer.prototype
p.off = function(eventName, fn){
 let listener = this.listener = this.listener || [];
 let actionArray = listener[eventName];
 if(typeof eventName === 'string' && Array.isArray(actionArray)){
  if(typeof fn === 'function'){
   actionArray.forEach( (func, i, arr) => {
    if(func === fn){
     arr.splice(i,1); 
    }
   });
  }
 }
}

触发事件方法:

//let p = Observer.prototype
p.emit = function(eventName){
 let listener = this.listener = this.listener || [];
 let actionArray = listener[eventName];
 if(Array.isArray(actionArray)){
  actionArray.forEach( func => {
   if(typeof func === 'function'){
    func(); 
   }
  }); 
 }
}

其次,就是当数据变动,触发自身相关事件后,怎么一路冒泡到根结点的处理了。

怎么冒泡到根结点呢?

那就自身结点关联父结点嘛,这样不就可以追溯到根节点了么。

所以,我们在Observer.walk时,就将自己的父节点记录即可,如下:

//let p = Observer.prototype
p.observe = function(key, data){
 if(typeof data === 'object'){
  let ob = new Observer(data); 
  //关联父节点
  ob._parent = {
   key,
   ob: this
  };
 } 
}

最后,有了子父结点的依赖关系,那么冒泡方法就OK啦,如下:

//let p = Observer.prototype
p.notify = function(eventName){
 let ob = this._parent && this._parent.ob;
 let key = ob && this._parent.key || 'root';
 console.log('parent--'+key+' event--'+eventName);
 this.emit(eventName);
 //判断节点是否有父节点,若有,就向上传递事件
 ob && ob.notify(eventName); 
}

Perfect,具体代码详见github.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Gird组件 Part-3:范例RSSFeed Viewer
Mar 10 Javascript
javascript定时变换图片实例代码
Mar 17 Javascript
js网页滚动条滚动事件实例分析
May 05 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
Feb 19 Javascript
每日十条JavaScript经验技巧(一)
Jun 23 Javascript
使用Ajax与服务器(JSON)通信实例
Nov 04 Javascript
详解plotly.js 绘图库入门使用教程
Feb 23 Javascript
解决vue router组件状态刷新消失的问题
Aug 01 Javascript
使用JavaScript解析URL的方法示例
Mar 01 Javascript
微信小程序实现圆形进度条动画
Nov 18 Javascript
解决Vue调用springboot接口403跨域问题
Sep 02 Javascript
vue-property-decorator用法详解
Dec 12 Javascript
利用HTML5+Socket.io实现摇一摇控制PC端歌曲切换
Jan 13 #Javascript
使用jQuery的ajax方法向服务器发出get和post请求的方法
Jan 13 #Javascript
jquery,js简单实现类似Angular.js双向绑定
Jan 13 #Javascript
jQuery实现的简单排序功能示例【冒泡排序】
Jan 13 #Javascript
js实现淡入淡出轮播切换功能
Jan 13 #Javascript
js仿百度音乐全选操作
Jan 13 #Javascript
js实现tab选项卡切换功能
Jan 13 #Javascript
You might like
php 动态执行带有参数的类方法
2009/04/10 PHP
php下获取客户端ip地址的函数
2010/03/15 PHP
使用URL传输SESSION信息
2015/07/14 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
2015/11/15 PHP
PHP递归遍历多维数组实现无限分类的方法
2016/05/06 PHP
Yii2使用dropdownlist实现地区三级联动功能的方法
2016/07/18 PHP
PHP的Json中文处理解决方案
2016/09/29 PHP
javascript 限制输入和粘贴(IE,firefox测试通过)
2008/11/14 Javascript
jquery last-child 列表最后一项的样式
2010/01/22 Javascript
在一个浏览器里呈现所有浏览器测试结果的前端测试工具的思路
2010/03/02 Javascript
jqPlot 基于jquery的画图插件
2011/04/26 Javascript
不用锚点也可以平滑滚动到页面的指定位置实现代码
2013/05/08 Javascript
jquery原创弹出层折叠效果点击折叠弹出一个层
2014/03/12 Javascript
checkbox勾选判断代码分析
2014/06/11 Javascript
jquery引用方法时传递参数原理分析
2014/10/13 Javascript
浅谈JSON中stringify 函数、toJosn函数和parse函数
2015/01/26 Javascript
JS实现很酷的水波文字特效实例
2015/02/26 Javascript
JS根据key值获取URL中的参数值及把URL的参数转换成json对象
2015/08/26 Javascript
关于JavaScript限制字数的输入框的那些事
2016/08/14 Javascript
通过扫描二维码打开app的实现代码
2016/11/10 Javascript
微信小程序之仿微信漂流瓶实例
2016/12/09 Javascript
简单实现jquery焦点图
2016/12/12 Javascript
Python中设置变量访问权限的方法
2015/04/27 Python
python中解析json格式文件的方法示例
2017/05/03 Python
python 实现将Numpy数组保存为图像
2020/01/09 Python
python 项目目录结构设置
2020/02/14 Python
如何利用python进行时间序列分析
2020/08/04 Python
美国性感女装网站:bebe
2017/03/04 全球购物
Perfumetrader荷兰:香水、化妆品和护肤品在线商店
2017/09/15 全球购物
新闻记者个人求职的自我评价
2013/11/28 职场文书
入党自我评价范文
2014/02/02 职场文书
发布会邀请函
2015/01/31 职场文书
基于Python的EasyGUI学习实践
2021/05/07 Python
Python使用scapy模块发包收包
2021/05/07 Python
OpenCV-Python 实现两张图片自动拼接成全景图
2021/06/11 Python
Java虚拟机内存结构及编码实战分享
2022/04/07 Java/Android