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 】
相关推荐:
如何在阿里云部署织梦网站?
国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?
ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集
利用vue写todolist单页应用
如何在景安服务器上快速搭建个人网站?
清除minerd进程的简单方法
最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?
如何在万网主机上快速搭建网站?
高端企业智能建站程序:SEO优化与响应式模板定制开发
详解免费开源的.NET多类型文件解压缩组件SharpZipLib(.NET组件介绍之七)
如何打造高效商业网站?建站目的决定转化率
百度输入法全感官ai怎么关 百度输入法全感官皮肤关闭
php json中文编码为null的解决办法
深入理解Android中的xmlns:tools属性
,在苏州找工作,上哪个网站比较好?
php打包exe后无法访问网络共享_共享权限设置方法【教程】
html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】
品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?
Laravel怎么为数据库表字段添加索引以优化查询
深圳网站制作的公司有哪些,dido官方网站?
Python3.6正式版新特性预览
浅谈Javascript中的Label语句
Laravel怎么上传文件_Laravel图片上传及存储配置
Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载
制作电商网页,电商供应链怎么做?
如何破解联通资金短缺导致的基站建设难题?
Laravel如何与Vue.js集成_Laravel + Vue前后端分离项目搭建指南
Java解压缩zip - 解压缩多个文件或文件夹实例
EditPlus中的正则表达式实战(6)
利用python获取某年中每个月的第一天和最后一天
Laravel如何记录自定义日志?(Log频道配置)
Android自定义控件实现温度旋转按钮效果
Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】
Laravel如何使用Contracts(契约)进行编程_Laravel契约接口与依赖反转
Laravel如何创建自定义Facades?(详细步骤)
Laravel如何使用Guzzle调用外部接口_Laravel发起HTTP请求与JSON数据解析【详解】
标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析
如何利用DOS批处理实现定时关机操作详解
Swift中switch语句区间和元组模式匹配
电商网站制作价格怎么算,网上拍卖流程以及规则?
南京网站制作费用,南京远驱官方网站?
Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】
HTML透明颜色代码怎么让图片透明_给img元素加透明色的技巧【方法】
Python自然语言搜索引擎项目教程_倒排索引查询优化案例
HTML 中动态设置元素 name 属性的正确语法详解
Laravel模型关联查询教程_Laravel Eloquent一对多关联写法
在Oracle关闭情况下如何修改spfile的参数
JavaScript如何操作视频_媒体API怎么控制播放
香港服务器WordPress建站指南:SEO优化与高效部署策略
如何快速搭建个人网站并优化SEO?

