vue.js设计与实现(分支切换与cleanup)
如存在三元运算符时,怎么处理
// 原始数据
const data = { text: 'hello world',ok:true}// 副作用函数存在三元运算符
effect(function effectFn(){document.body.innerText = obj.ok ? obj.text : 'not'
})// 理解如此,obj.ok和obj.text都会绑定effectFn函数,所以不管obj.ok 是true还是false ,obj.text值改变都会执行effectFn副作用函数,然而当obj.ok为false时,obj.text值无论怎么改变,都不应该执行effectFn副作用函数。
解决方案:每次执行副作用 函数,可以先把它从所有与之关联的依赖集合中删除。当副作用函数执行完后,会重新建立关系。
// 用一个全局变量储存被注册的副作用函数
let activeEffect// effect 函数用于注册副作用函数
function effect(fn){// 当 effectFn 执行时,将其设置为当前激活的副作用函数const effectFn = ()=>{// 调用cleanup完成清除工作cleanup(effectFn)// 当调用effect注册副作用函数时,将副作用函数fn赋值给activeEffectactiveEffect = effectFn// 执行副作用函数fn()}// activeEffect.deps 用来存储所有与被副作用函数相关的依赖集合effectFn.deps = []// 执行副作用函数effectFn()
}// 清除工作
function cleanup(effectFn){// 遍历`effectFn.deps 数组for(let i=0; i< effectFn.deps.length; i++){// deps 是依赖集合const deps = effectFn.deps[i]// 将 effectFn 从依赖集合中移除deps.delete(effectFn)}// 最后需要重置 effectFn.deeps 数组effectFn.deps.length = 0
}// 储存副作用函数的桶
const bucket = new WeakMap()// 原始数据
const data = { text: 'hello world',ok:true}// 对原始数据的代理
const obj = new Proxy(data,{// 拦截读取操作get(target,key){track(target,key)// 返回属性值return target[key]},// 拦截设置操作set(target,key,newValue){console.log('bucket:',bucket)// 设置属性值target[key] = newValuetrigger(target,key)return true}
})// 在 get 拦截函数内调用 track 函数追踪变化
function track(target,key){// 没有 activeEffect 直接 returnif(!activeEffect) return target[key]// 根据 target 从 “桶” 中 取得 depsMap,它也是一个map 类型 key --》effectslet depsMap = bucket.get(target)// 如果不存在 depsMap 那么新建一个Map 并与 target 关联if(!depsMap){bucket.set(target,(depsMap = new Map()))}// 再根据 key 从 depsMap 中取得 deps,它是一个 set 类型// 里面储存着所有与当前key 相关联的副作用函数,effectslet deps = depsMap.get(key)// 如果 deps 不存在 同样新建一个set 并与 key 关联if(!deps){depsMap.set(key,(deps = new Set()))}// 最后将当前激活的副作用函数添加到“桶”deps.add(activeEffect)// deps 就是一个与当前副作用函数存在关联的依赖集合// 将其添加到activeEffect.deps 数组中activeEffect.deps.push(deps) // 新增
}
// 在 set 拦截函数内调用 trigger 函数 触发变化
function trigger(target,key){// 根据 target 从桶中取得 depsMap,它是key --》effectsconst depsMap = bucket.get(target)if(!depsMap) return true// 根据 key 取得所有副作用函数 effectsconst effects = depsMap.get(key)// new Set 是为了防止 effectFn 执行时,进行无限的循环const effectsToRun = new Set(effects)effectsToRun.forEach(effectFn => effectFn())// 执行副作用函数// effects && effects.forEach(fn => fn())
}// 执行副作用函数,触发读取
effect(function effectFn(){document.body.innerText = obj.ok ? obj.text : 'not'
})// 1 秒后修改响应式数据
setTimeout(()=>{obj.text = 'hello vue3'
},1000)setTimeout(()=>{obj.ok = false
},3000)
相关文章:
vue.js设计与实现(分支切换与cleanup)
如存在三元运算符时,怎么处理 // 原始数据 const data { text: hello world,ok:true}// 副作用函数存在三元运算符 effect(function effectFn(){document.body.innerText obj.ok ? obj.text : not })// 理解如此,obj.ok和obj.text都会绑定effectFn函…...

206基于matlab的无人机航迹规划(UAV track plannin)
基于matlab的无人机航迹规划(UAV track plannin)。输入输出参数包括 横滚、俯仰、航向角(单位:度);横滚速率、俯仰速率、航向角速率(单位:度/秒);飞机运动速度——X右翼、…...
【Linux 】查看veth-pair对的映射关系
1. 查看当前存在的ns ip netns add netns199 //新建一个命名空间 # ip netns show netns199 (id: 3)可以看到一个名称叫做netns199 的命名空间,其 id为3 2. 创建一个对,并加入其中一个到其他命名空间中 $ sudo ip link add veth100 type veth peer n…...

Cisco Firepower FMCv修改管理Ip方法
FMCv 是部署在VMWARE虚拟平台上的FMC 部署完成后,如何修改管理IP 1 查看当前版本 show version 可以看到是for VMware 2 修改管理IP步骤 2.1 进入expert模式 expert2.2 进入超级用户 sudo su并输入密码 2.3 查看当前网卡Ip 2.4 修改Ip 命令: /…...

PHP开发全新29网课交单平台源码修复全开源版本,支持聚合登陆易支付
这是一套最新版本的PHP开发的网课交单平台源代码,已进行全开源修复,支持聚合登录和易支付功能。 项目 地 址 : runruncode.com/php/19721.html 以下是对该套代码的主要更新和修复: 1. 移除了论文编辑功能。 2. 移除了强国接码…...

【Web前端】CSS基本语法规范和引入方式常见选择器用法常见元素属性
一、基本语法规范 选择器 {一条/N条声明} 选择器决定针对谁修改 (找谁) 声明决定修改什么.。(干什么) 声明的属性是键值对.。使用 : 区分键值对, 使用 : 区分键和值。 <!DOCTYPE html> <html lang"en"> <head>&…...

SnapGene 5 for Mac 分子生物学软件
SnapGene 5 for Mac是一款专为Mac操作系统设计的分子生物学软件,以其强大的功能和用户友好的界面,为科研人员提供了高效、便捷的基因克隆和分子实验设计体验。 软件下载:SnapGene 5 for Mac v5.3.1中文激活版 这款软件支持DNA构建和克隆设计&…...

本地部署大模型的几种工具(上-相关使用)
目录 前言 为什么本地部署 目前的工具 vllm 介绍 下载模型 安装vllm 运行 存在问题 chatglm.cpp 介绍 下载 安装 运行 命令行运行 webdemo运行 GPU推理 ollama 介绍 下载 运行 运行不同参数量的模型 存在问题 lmstudio 介绍 下载 使用 下载模型文件…...
Spring Boot集成itext实现html生成PDF功能
1.itext介绍 iText是著名的开放源码的站点sourceforge一个项目,是用于生成PDF文档的一个java类库。通过iText不仅可以生成PDF或rtf的文档,而且可以将XML、Html文件转化为PDF文件 iText 的特点 以下是 iText 库的显着特点 − Interactive − iText 为你提供类(API)来生成…...
Java 多态、包、final、权限修饰符、静态代码块
多态 Java多态是指一个对象可以具有多种形态。它是面向对象编程的一个重要特性,允许子类对象可以被当作父类对象使用。多态的实现主要依赖于继承、接口和方法重写。 在Java中,多态的实现主要通过以下两种方式: 继承:子类继承父类…...

基于Spring boot + Vue协同过滤算法的电影推荐系统
末尾获取源码作者介绍:大家好,我是墨韵,本人4年开发经验,专注定制项目开发 更多项目:CSDN主页YAML墨韵 学如逆水行舟,不进则退。学习如赶路,不能慢一步。 目录 一、项目简介 二、开发技术与环…...

Chrome之解决:浏览器插件不能使用问题(十三)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

【正版特惠】IDM 永久授权 优惠低至109元!
尽管小编有修改版IDM,但是由于软件太好用了,很多同学干脆就直接购买了正版,现在正版也不贵,并且授权码绑定自己的邮箱,直接官方下载激活,无需其他的绿化修改之类的操作,不喜欢那么麻烦的&#x…...
SpringBoot与Prometheus监控整合
参考: springboot实战之prometheus监控整合-腾讯云开发者社区-腾讯云 https://www.cnblogs.com/skevin/p/15874139.html https://www.jianshu.com/p/e5dc2b45c7a4...

Linux 系统 docker搭建LNMP环境
1、安装nginx docker pull nginx (默认安装的是最新版本) 2、运行nginx docker run --name nginx -p 80:80 -d nginx:latest 备注:--name nginx 表示容器名为 nginx -d 表示后台运行 -p 80:80 表示把本地80端口绑定到Nginx服务端的 80端口 nginx:lates…...
拉普拉斯变换
定义: 拉普拉斯变换是一种在信号处理、控制理论和其他领域中广泛使用的数学工具,用于将一个函数从时域转换到复频域。拉普拉斯变换将一个函数 f(t) 变换为一个复变量函数 F(s),其中 s 是复数变量。下面是拉普拉斯变换的推导过程:…...
Mashup-Math_Topic_One
Tutorial and Introspection A Rudolf and 121 注意到第 1 1 1 位只能被第 2 2 2 位影响,以此类推位置,对于 a i a_i ai , 如果 < 0 < 0 <0 ,不合法 ; 否则, a i − a i , a i 1 − 2 ∗ a i , a i 2 − a …...

基于JavaWEB SSM SpringBoot婚纱影楼摄影预约网站设计和实现
基于JavaWEB SSM SpringBoot婚纱影楼摄影预约网站设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…...

逐步学习Go-Select多路复用
概述 这里又有多路复用,但是Go中的这个多路复用不同于网络中的多路复用。在Go里,select用于同时等待多个通信操作(即多个channel的发送或接收操作)。Go中的channel可以参考我的文章:逐步学习Go-并发通道chan(channel)…...
王道:OJ15
课时15作业 Description 读取10个元素 87 7 60 80 59 34 86 99 21 3,然后建立二叉查找树,排序后输出3 7 21 34 59 60 80 86 87 99,针对有序后的元素,存入一个长度为10的数组中,通过折半查找找到21的下标(…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
前端倒计时误差!
提示:记录工作中遇到的需求及解决办法 文章目录 前言一、误差从何而来?二、五大解决方案1. 动态校准法(基础版)2. Web Worker 计时3. 服务器时间同步4. Performance API 高精度计时5. 页面可见性API优化三、生产环境最佳实践四、终极解决方案架构前言 前几天听说公司某个项…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...