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 相关文章推荐
使用javascript访问XML数据的实例
Dec 27 Javascript
Javascript 静态页面实现随机显示广告的办法
Nov 17 Javascript
javascript实现获取cookie过期时间的变通方法
Aug 14 Javascript
JavaScript动态修改弹出窗口大小的方法
Apr 06 Javascript
js前端面试题及答案整理(一)
Aug 26 Javascript
Node.js实现连接mysql数据库功能示例
Sep 15 Javascript
JavaScript求一个数组中重复出现次数最多的元素及其下标位置示例
Jul 23 Javascript
微信小程序实现的日期午别医生排班表功能示例
Jan 09 Javascript
使用layui日期控件laydate对开始和结束时间进行联动控制的方法
Sep 06 Javascript
jquery实现点击弹出对话框
Feb 08 jQuery
es6数组的flat(),flatMap()函数用法实例分析
Apr 18 Javascript
vue-quill-editor插入图片路径太长问题解决方法
Jan 08 Vue.js
利用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输出控制功能在简繁体转换中的应用
2006/10/09 PHP
php 攻击方法之谈php+mysql注射语句构造
2009/10/30 PHP
PHP多线程之内部多线程实例分析
2015/03/09 PHP
php实现的通用图片处理类
2015/03/24 PHP
thinkPHP框架实现多表查询的方法
2018/06/14 PHP
Ctrl+Enter提交内容信息
2006/06/26 Javascript
JQuery从头学起第一讲
2010/07/04 Javascript
图片无缝滚动代码(向左/向下/向上)
2013/04/10 Javascript
JS控制图片翻转示例代码(兼容firefox,ie,chrome)
2013/12/19 Javascript
js+css实现导航效果实例
2015/02/10 Javascript
js控制文本框输入的字符类型方法汇总
2015/06/19 Javascript
jQuery实现网站添加高亮突出显示效果的方法
2015/06/26 Javascript
jQuery实现气球弹出框式的侧边导航菜单效果
2015/09/22 Javascript
详解nodejs中exports和module.exports的区别
2017/02/17 NodeJs
Vue+SpringBoot开发V部落博客管理平台
2017/12/27 Javascript
深入理解使用Vue实现Context-Menu的思考与总结
2019/03/09 Javascript
bootstrap-table formatter 使用vue组件的方法
2019/05/09 Javascript
浅谈vue异步数据影响页面渲染
2019/10/29 Javascript
Vue搭建后台系统需要注意的问题
2019/11/08 Javascript
vant 自定义 van-dropdown-item的用法
2020/08/05 Javascript
vue绑定数字类型 value为数字的实例
2020/08/31 Javascript
[16:56]教你分分钟做大人:司夜刺客
2014/10/30 DOTA
[01:05:40]VG vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
详解在Python程序中自定义异常的方法
2015/10/16 Python
Python实现的计数排序算法示例
2017/11/29 Python
Python之pandas读写文件乱码的解决方法
2018/04/20 Python
Python子类继承父类构造函数详解
2019/02/19 Python
python rsync服务器之间文件夹同步脚本
2019/08/29 Python
python和php哪个容易学
2020/06/19 Python
python怎么判断素数
2020/07/01 Python
CSS中几个与换行有关的属性简明总结
2014/04/15 HTML / CSS
HTML5 history新特性pushState、replaceState及两者的区别
2015/12/26 HTML / CSS
HTML5单页面手势滑屏切换原理分析
2017/07/10 HTML / CSS
代办委托书怎样写
2014/04/08 职场文书
2014年售票员工作总结
2014/11/19 职场文书
全家福照片寄语怎么写?
2019/04/02 职场文书