Vue数据驱动模拟实现5

发布时间 - 2026-01-10 22:30:10    点击率:

一、前言

在"模拟Vue之数据驱动4"中,我们实现了push、pop等数组变异方法。

但是,在随笔末尾我们提到,当pop、sort这些方法触发后,该怎么办呢?因为其实,它们并没有往数组中新增属性呢。

而且,当数据改动后,如果我们在变动数据处,就立即更改数据也未免性能不够,此时,走读Vue源码,发现他用了一个很巧妙的方法,就是职责链模式。当某个数据有所变动时,它会向上传递,通俗点就是冒泡至根结点,这样我们也可以在自己代码中使用事件代理咯,哇卡哇卡。

示意图如下所示:

好了,说了这么多,我们下面就一起来实现下吧。

二、正文

注:以下代码皆编写在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.

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


# Vue  # 数据驱动  # Vue数据驱动表单渲染  # 轻松搞定form表单  # 浅谈vuejs实现数据驱动视图原理  # 详解VueJS 数据驱动和依赖追踪分析  # Vue数据驱动模拟实现4  # Vue数据驱动模拟实现2  # Vue数据驱动模拟实现1  # Vue数据驱动模拟实现3  # 详解Vue数据驱动原理  # 自定义  # 自己的  # 好了  # 那就  # 说了  # 这么多  # 用了  # 不就  # 所示  # 若有  # 就将  # 它会  # 写在  # 绑定  # 就向  # 大家多多  # 下吧  # 追溯到  # 组中  # 实现了 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: 免费视频制作网站,更新又快又好的免费电影网站?  VIVO手机上del键无效OnKeyListener不响应的原因及解决方法  谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复  网站优化排名时,需要考虑哪些问题呢?  Laravel Octane如何提升性能_使用Laravel Octane加速你的应用  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工  Laravel如何处理JSON字段_Eloquent原生JSON字段类型操作教程  javascript中的try catch异常捕获机制用法分析  Laravel如何为API编写文档_Laravel API文档生成与维护方法  php读取心率传感器数据怎么弄_php获取max30100的心率值【指南】  电商网站制作价格怎么算,网上拍卖流程以及规则?  Laravel用户密码怎么加密_Laravel Hash门面使用教程  如何快速辨别茅台真假?关键步骤解析  Laravel如何集成Inertia.js与Vue/React?(安装配置)  惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?  Laravel如何处理表单验证?(Requests代码示例)  关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)  Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  如何在宝塔面板中修改默认建站目录?  Laravel如何使用集合(Collections)进行数据处理_Laravel Collection常用方法与技巧  Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作  如何用ChatGPT准备面试 模拟面试问答与职场话术练习教程  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted  如何在Windows虚拟主机上快速搭建网站?  Google浏览器为什么这么卡 Google浏览器提速优化设置步骤【方法】  JavaScript实现Fly Bird小游戏  javascript事件捕获机制【深入分析IE和DOM中的事件模型】  Laravel如何使用Service Container和依赖注入?(代码示例)  javascript基本数据类型及类型检测常用方法小结  如何快速启动建站代理加盟业务?  Laravel怎么判断请求类型_Laravel Request isMethod用法  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  Laravel怎么配置.env环境变量_Laravel生产环境敏感数据保护与读取【方法】  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  Laravel如何实现本地化和多语言支持?(i18n教程)  如何快速上传建站程序避免常见错误?  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  JavaScript如何实现类型判断_typeof和instanceof有什么区别  香港服务器网站卡顿?如何解决网络延迟与负载问题?  Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道  如何在景安云服务器上绑定域名并配置虚拟主机?  Laravel的HTTP客户端怎么用_Laravel HTTP Client发起API请求教程  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  如何快速上传自定义模板至建站之星?  Laravel项目怎么部署到Linux_Laravel Nginx配置详解  怎样使用JSON进行数据交换_它有什么限制  如何批量查询域名的建站时间记录?  高端建站如何打造兼具美学与转化的品牌官网?