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 实现父窗口引用弹出窗口的值的脚本
Aug 07 Javascript
JavaScript 面向对象的 私有成员和公开成员
May 13 Javascript
javascript实现图片上传前台页面
Aug 18 Javascript
多种js图片预加载实现方式分享
Feb 19 Javascript
servlet+jquery实现文件上传进度条示例代码
Jan 25 Javascript
js实现一个猜数字游戏
Mar 31 Javascript
微信小程序 聊天室简单实现
Apr 19 Javascript
详解ECMAScript6入门--Class对象
Apr 27 Javascript
浅谈ECMAScript6新特性之let、const
Aug 02 Javascript
深入浅析JSONAPI在PHP中的应用
Dec 24 Javascript
Webpack 之 babel-loader文件预处理器详解
Mar 23 Javascript
基于vue和bootstrap实现简单留言板功能
May 30 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
SONY SRF-40W电路分析
2021/03/02 无线电
php文件打包 下载之使用PHP自带的ZipArchive压缩文件并下载打包好的文件
2012/06/13 PHP
PHP中魔术变量__METHOD__与__FUNCTION__的区别
2014/09/29 PHP
Yii中Model(模型)的创建及使用方法
2015/12/28 PHP
php外部执行命令函数用法小结
2016/10/11 PHP
php数据序列化测试实例详解
2017/08/12 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
2018/02/19 PHP
Yii框架 session 数据库存储操作方法示例
2019/11/18 PHP
jQuery .tmpl(), .template()学习资料小结
2011/07/18 Javascript
js/ajax跨越访问-jsonp的原理和实例(javascript和jquery实现代码)
2012/12/27 Javascript
javascript格式化指定日期对象的方法
2015/04/21 Javascript
网页从弹窗页面单选框传值至父页面代码分享
2015/09/29 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
2015/10/26 Javascript
使用RequireJS库加载JavaScript模块的实例教程
2016/06/06 Javascript
js H5 canvas投篮小游戏
2016/08/18 Javascript
JavaScript实现星星等级评价功能
2017/03/22 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
2020/06/29 Javascript
bootstrap动态添加面包屑(breadcrumb)及其响应事件的方法
2017/05/25 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
Openlayers实现扩散的动态点(水纹效果)
2020/08/17 Javascript
Python遍历目录的4种方法实例介绍
2015/04/13 Python
pandas 小数位数 精度的处理方法
2018/06/09 Python
利用python对Excel中的特定数据提取并写入新表的方法
2018/06/14 Python
python如何实现数据的线性拟合
2019/07/19 Python
tornado+celery的简单使用详解
2019/12/21 Python
python构造函数init实例方法解析
2020/01/19 Python
Aquatalia官网:意大利著名鞋履品牌
2019/09/26 全球购物
毕业生就业推荐信范文
2013/12/01 职场文书
有创意的广告词
2014/03/18 职场文书
医院节能减排方案
2014/06/13 职场文书
2015年考研复习计划
2015/01/19 职场文书
公路施工安全责任书
2015/05/08 职场文书
幼师辞职信范文大全
2015/05/12 职场文书
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android
Python实现双向链表基本操作
2022/05/25 Python
浅谈css清除浮动(clearfix和clear)的用法
2023/05/21 HTML / CSS