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 相关文章推荐
artDialog 4.1.5 Dreamweaver代码提示/补全插件 附下载
Jul 31 Javascript
js三种排序算法分享
Aug 16 Javascript
JS、CSS加载中的小问题探讨
Nov 26 Javascript
jquery实现瀑布流效果分享
Mar 26 Javascript
javascript正则表达式使用replace()替换手机号的方法
Jan 19 Javascript
Angular2  NgModule 模块详解
Oct 19 Javascript
QRCode.js:基于JQuery的生成二维码JS库的使用
Jun 23 jQuery
angularjs2 ng2 密码隐藏显示的实例代码
Aug 01 Javascript
JavaScript中使用Async实现异步控制
Aug 15 Javascript
在vue中使用Autoprefixed的方法
Jul 27 Javascript
在小程序中集成redux/immutable/thunk第三方库的方法
Aug 12 Javascript
angular的输入和输出的使用方法
Sep 22 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
建立文件交换功能的脚本(三)
2006/10/09 PHP
php自动适应范围的分页代码
2008/08/05 PHP
用php获取本周,上周,本月,上月,本季度日期的代码
2009/08/05 PHP
php截取指定2个字符之间字符串的方法
2015/04/15 PHP
理清PHP在Linxu下执行时的文件权限方法
2017/06/07 PHP
PHP SFTP实现上传下载功能
2017/07/26 PHP
IE autocomplete internet explorer's autocomplete
2007/06/30 Javascript
jquery插件jbox使用iframe关闭问题
2009/02/09 Javascript
jQuery 下拉列表 二级联动插件分享
2012/03/29 Javascript
js修改地址栏URL参数解决url参数问题
2012/12/15 Javascript
验证码在IE中不刷新而谷歌等浏览器正常的解决方案
2014/03/18 Javascript
js判断上传文件类型判断FileUpload文件类型代码
2014/05/20 Javascript
javascript arguments使用示例
2014/12/16 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
JS+CSS实现的经典tab选项卡效果代码
2015/09/16 Javascript
Bootstrap模态框(modal)垂直居中的实例代码
2016/08/18 Javascript
BootStrap 动态添加验证项和取消验证项的实现方法
2016/09/28 Javascript
JS原型继承四步曲及原型继承图一览
2017/11/28 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
2020/06/19 Javascript
[07:12]2014DOTA2西雅图国际邀请赛 黑马Liquid专题采访
2014/07/12 DOTA
Python实现的彩票机选器实例
2015/06/17 Python
python实现简单socket通信的方法
2016/04/19 Python
python isinstance函数用法详解
2020/02/13 Python
Python 实现PS滤镜的旋涡特效
2020/12/03 Python
华丽的手绘陶瓷:MacKenzie-Childs
2017/02/04 全球购物
Lulu Guinness露露·吉尼斯官网:红唇包
2019/02/03 全球购物
建筑毕业生自我鉴定
2013/10/18 职场文书
商场经理竞聘演讲稿
2014/01/01 职场文书
公司离职证明范本(5篇)
2014/09/17 职场文书
学校法制宣传日活动总结
2014/11/01 职场文书
终止劳动合同证明书样本
2014/11/19 职场文书
小学教师党员承诺书
2015/04/27 职场文书
大学生求职意向书
2015/05/11 职场文书
请求模块urllib之PYTHON爬虫的基本使用
2022/04/08 Python
vue postcss-px2rem 自适应布局
2022/05/15 Vue.js
jdbc中自带MySQL 连接池实践示例
2022/07/23 MySQL