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-Mozilla和IE中的一个函数直接量的问题
Jan 09 Javascript
基于逻辑运算的简单权限系统(实现) JS 版
Mar 24 Javascript
html中table数据排序的js代码
Aug 09 Javascript
扩展JavaScript功能的正确方法(译文)
Apr 12 Javascript
各浏览器中querySelector和querySelectorAll的实现差异分析
May 23 Javascript
js 获取input点选按钮的值的方法
Apr 14 Javascript
JS生成随机字符串的多种方法
Jun 10 Javascript
5种处理js跨域问题方法汇总
Dec 04 Javascript
完美兼容多浏览器的js判断图片路径代码汇总
Apr 17 Javascript
js 奇葩技巧之隐藏代码
Aug 11 Javascript
浅谈vue项目如何打包扔向服务器
May 08 Javascript
js实现聊天对话框
Feb 08 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
肝肠寸断了解下!盘点史上最伤心的十大动漫
2020/03/04 日漫
浅谈PHP强制类型转换,慎用!
2013/06/06 PHP
PHP取二进制文件头快速判断文件类型的实现代码
2013/08/05 PHP
php实现按文件名搜索文件的远程文件查找器
2014/05/10 PHP
PHP代码维护,重构变困难的4种原因分析
2016/01/25 PHP
PHP错误机制知识汇总
2016/03/24 PHP
关于laravel 日志写入失败问题汇总
2019/10/17 PHP
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
Javascript基础教程之关键字和保留字汇总
2015/01/18 Javascript
pace.js页面加载进度条插件
2015/09/29 Javascript
基于BootStrap的前端分页带省略号和上下页效果
2017/05/18 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
浅谈Vue SSR 的 Cookies 问题
2017/11/20 Javascript
AngularJS自定义过滤器用法经典实例总结
2018/05/17 Javascript
JS实现快递单打印功能【推荐】
2018/06/21 Javascript
微信小程序实现倒计时补零功能
2018/07/09 Javascript
Bootstrap 模态框自定义点击和关闭事件详解
2018/08/10 Javascript
vue router 跳转时打开新页面的示例方法
2019/07/28 Javascript
vue集成chart.js的实现方法
2019/08/20 Javascript
基于javascript的无缝滚动动画1
2020/08/07 Javascript
[54:58]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第一场 11.25
2020/11/25 DOTA
python通过pil将图片转换成黑白效果的方法
2015/03/16 Python
放弃 Python 转向 Go语言有人给出了 9 大理由
2017/10/20 Python
Python+tkinter模拟“记住我”自动登录实例代码
2018/01/16 Python
Python二元算术运算常用方法解析
2020/09/15 Python
UI自动化定位常用实现方法代码示例
2020/10/27 Python
Python 调用 ES、Solr、Phoenix的示例代码
2020/11/23 Python
pycharm 的Structure界面设置操作
2021/02/05 Python
CSS3实现可爱的小黄人动画
2016/07/11 HTML / CSS
美国宠物美容和宠物用品购物网站:Cherrybrook
2018/12/07 全球购物
C#实现启动一个进程
2016/10/01 面试题
将相和教学反思
2014/02/04 职场文书
教师三严三实心得体会
2014/10/11 职场文书
全国法制宣传日活动总结2014
2014/11/01 职场文书
技术负责人岗位职责
2015/02/10 职场文书
apache基于端口创建虚拟主机的示例
2021/04/22 Servers