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 相关文章推荐
基于jquery实现的定时显示与隐藏div广告的实现代码
Aug 22 Javascript
JQuery仿小米手机抢购页面倒计时效果
Dec 16 Javascript
javascript实现检验的各种规则
Jul 31 Javascript
Angular.js如何从PHP读取后台数据
Mar 24 Javascript
bootstrap3 兼容IE8浏览器!
May 02 Javascript
浅谈jquery点击label触发2次的问题
Jun 12 Javascript
Bootstrap 填充Json数据的实例代码
Jan 11 Javascript
实例解析ES6 Proxy使用场景介绍
Jan 08 Javascript
微信 jssdk 签名错误invalid signature的解决方法
Jan 14 Javascript
vue 实现购物车总价计算
Nov 06 Javascript
解决vuex数据页面刷新后初始化操作
Jul 26 Javascript
js实现盒子移动动画效果
Aug 09 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 转义使用详解
2013/07/15 PHP
取得单条网站评论以数组形式进行输出
2014/07/28 PHP
浅谈PHP正则表达式中修饰符/i, /is, /s, /isU
2014/10/21 PHP
PHP文件锁函数flock()详细介绍
2014/11/18 PHP
mod_php、FastCGI、PHP-FPM等PHP运行方式对比
2015/07/02 PHP
PHP面向对象程序设计重载(overloading)操作详解
2019/06/13 PHP
laravel框架实现后台登录、退出功能示例
2019/10/31 PHP
javascript的动态加载、缓存、更新以及复用(一)
2014/06/09 Javascript
JavaScript中发布/订阅模式的简单实例
2014/11/05 Javascript
js实现简单的左右两边固定广告效果实例
2015/04/10 Javascript
关于JavaScript作用域你想知道的一切
2016/02/04 Javascript
js操作DOM--添加、删除节点的简单实例
2016/07/08 Javascript
JS实现复选框的全选和批量删除功能
2017/04/05 Javascript
[js高手之路]图解javascript的原型(prototype)对象,原型链实例
2017/08/28 Javascript
JavaScript编程设计模式之观察者模式(Observer Pattern)实例详解
2017/10/25 Javascript
Vue源码学习之初始化模块init.js解析
2017/11/02 Javascript
浅谈react受控组件与非受控组件(小结)
2018/02/09 Javascript
angularJs在多个控制器中共享服务数据的方法
2018/09/30 Javascript
微信小程序实现Session功能及无法获取session问题的解决方法
2019/05/07 Javascript
node express使用HTML模板的方法示例
2019/08/22 Javascript
jQuery实现动态操作table行
2020/11/23 jQuery
Python实现遍历windows所有窗口并输出窗口标题的方法
2015/03/13 Python
Python合并两个字典的常用方法与效率比较
2015/06/17 Python
Python引用类型和值类型的区别与使用解析
2017/10/17 Python
Python cookbook(数据结构与算法)实现优先级队列的方法示例
2018/02/18 Python
python如何去除字符串中不想要的字符
2020/07/05 Python
python3如何将docx转换成pdf文件
2018/03/23 Python
python解决js文件utf-8编码乱码问题(推荐)
2018/05/02 Python
Python给定一个句子倒序输出单词以及字母的方法
2018/12/20 Python
python使用梯度下降和牛顿法寻找Rosenbrock函数最小值实例
2020/04/02 Python
在PyCharm中安装PaddlePaddle的方法
2021/02/05 Python
高山背包:High Sierra
2017/11/23 全球购物
2014年五四青年节演讲稿范文
2014/04/22 职场文书
机关党员进社区活动总结
2014/07/05 职场文书
学校元旦晚会开场白
2015/05/29 职场文书
婚宴新娘致辞
2015/07/28 职场文书