当前位置: 首页 > news >正文

Vue响应式原理三:响应式依赖收集-类

前提:实际开发中,响应式对象肯定是不止一个对象的, 使用数组reactiveFns, 所有依赖的函数都放到数组里面,是满足不了多个响应式对象,使用类单独来管理一个对象所有的依赖

1. 响应式依赖收集-类

  • 1.1. 类结构:创建Depend类来管理响应式依赖,包含reactiveFns数组存储依赖函数
  • 1.2. 核心方法:
  • addDepend(fn):添加依赖函数到数组,会先判断fn是否存在
  • notify():遍历执行所有收集的依赖函数
  • 代码如下:
	// 使用类单独来管理一个对象所有的依赖class Depend {constructor() {this.reactiveFns = [];}addDepend (fn) {if(fn) {// 将依赖函数添加到数组,this.reactiveFns.push(fn);}}notify () {this.reactiveFns.forEach(fn => {// 遍历执行所有收集的依赖函数fn()})}}
  • 1.3. 优势: 相比单一数组管理,可以针对不同对象创建独立的Depend实例,避免所有依赖混在一起
  • 1.4. 执行过程
    • 创建Depend实例:const dep = new Depend()
    • 收集依赖:通过watchFn函数调用dep.addDepend(fn)
    • 触发更新:修改属性后手动调用dep.notify()
    • 示例代码如下:
    	// 创建Depend实例const dep = new Depend()function watchFn (fn) {dep.addDepend(fn)// 传入函数后立即执行一次,类似watchEffect()fn()}// 响应式函数watchFn(function foo () {console.log('foo: ', obj.name);console.log('foo: ', obj.age);console.log('foo function');})watchFn(function bar () {console.log('bar: ', obj.name + ' hello');console.log('bar: ', obj.age + 10);console.log('bar function');})// 修改obj的属性obj.name = 'kobe'// 当依赖发生变化时,会执行对应的响应式函数dep.notify()```
    
  • 1.5. 当前问题:
  • 每次属性修改后需要手动调用dep.notify()
  • 容易遗漏导致依赖不更新
  • 多个属性变更时需要多次调用
	// 参考上面的代码...// 修改obj的属性console.log('name发生变化时----------------------------------------');obj.name = 'kobe'// 当依赖发生变化时,会执行对应的响应式函数dep.notify()// 再次修改obj的属性obj.name = 'james'// 每次手动通知,一旦忘记就不是响应式了// dep.notify()
    1. 完整代码如下:
       	// 使用类单独来管理一个对象所有的依赖class Depend {constructor() {this.reactiveFns = [];}addDepend (fn) {if(fn) {// 将依赖函数添加到数组,this.reactiveFns.push(fn);}}notify () {this.reactiveFns.forEach(fn => {// 遍历执行所有收集的依赖函数fn()})}}// 实际开发中,响应式对象肯定是不止一个对象的// 例如: // const user = { nickName: 'kobe', level: 100 }// const product = { name: '电脑', price: 1000 }// 有一个弊端,只有一个数组reactiveFns, 所有依赖的函数都放到数组里面,是满足不了多个响应式对象// 例如:一旦修改了product.name所有的响应式函数都会执行,目标是只想要执行product.name的响应式函数const obj = {name: 'why',age: 18}// 当上面有很多依赖函数时,很难收集// 设置一个专门执行响应式函数的一个函数const dep = new Depend()// obj => new Depend()// user => new Depend()// product => new Depend()function watchFn (fn) {dep.addDepend(fn)// 传入函数后立即执行一次,类似watchEffect()fn()}watchFn(function foo () {console.log('foo: ', obj.name);console.log('foo: ', obj.age);console.log('foo function');})watchFn(function bar () {console.log('bar: ', obj.name + ' hello');console.log('bar: ', obj.age + 10);console.log('bar function');})// 修改obj的属性console.log('name发生变化时----------------------------------------');obj.name = 'kobe'// 当依赖发生变化时,会执行对应的响应式函数dep.notify()// 修改obj的属性console.log('age发生变化时----------------------------------------');obj.age = 20dep.notify()console.log('name发生变化时----------------------------------------');obj.name = 'james'// 每次手动通知,一旦忘记就不是响应式了// dep.notify()```
    
  • 1.7. 后续改进:
  • 将展示如何自动创建依赖收集器
  • 实现属性变更自动通知机制
http://www.dtcms.com/a/271700.html

相关文章:

  • 大模型的下半场:从工具到智能体的产业变革与2025突围之路
  • AI大模型:(二)4.2 文生图训练实践-真人写实生成
  • 8.2 文档预处理模块(二)
  • 学习笔记(31):matplotlib绘制简单图表-直方图
  • UNet改进(19):基于残差注意力模块Residual Attention的高效分割网络设计
  • 编译安装的Mysql5.7报“Couldn‘t find MySQL server (mysqld_safe)“的原因 笔记250709
  • 主流大模型Agent框架 AutoGPT详解
  • 软件互联网产品发版检查清单
  • WIndows 编程辅助技能:格式工厂的使用
  • Dify教程更改文件上传数量限制和大小限制
  • JVM 调优
  • 双指针-15.三数之和-力扣(LeetCode)
  • AI技术如何重塑你的工作与行业?——实战案例解析与效率提升路径
  • gdb调试工具
  • Lingo软件学习(一)好学爱学
  • DPDK graph图节点处理框架:模块化数据流计算的设计与实现
  • dify配置邮箱,密码重置以及邮箱邀请加入
  • 【Java】【字节面试】字符串中 出现次数最多的字符和 对应次数
  • HTML应用指南:利用GET请求获取全国山姆门店位置信息
  • 跨服务sqlplus连接oracle数据库
  • 如何卸载本机的node.js
  • 源码角度解析 --- HashMap 的 get 和 put 流程
  • 前端使用fetch-event-source实现AI对话
  • AI Agent:我的第一个Agent项目
  • 爬虫-数据解析
  • [C语言初阶]操作符
  • ZeroMQ 代理架构实现(Python 服务端 + C++ 代理 + C++ 客户端)
  • RabbitMQ 4.1.1-Local random exchange体验
  • 解决Ollama下载太慢问题
  • Claude Code 环境搭建教程