概览

BaseReactiveHandler类的get方法中,有如下代码块if (!isReadonly2){track(target, "get", key);},这表示通过reactiveshallowReactive创建的响应式对象,非只读的,当读取代理对象proxyTarget的某个属性key时,都会被该get方法拦截,即调用track()方法建立依赖。

而当对代理对象proxyTarget进行赋值或更新某个属性的值时,会被set方法拦截,即调用trigger()方法触发依赖(而删除会被deleteProperty拦截)。

因此对于reactive响应式对象的响应式处理,和tracktrigger方法密不可分。

本文主要介绍tracktrigger是如何进行依赖的收集与触发的全流程。
在这里插入图片描述

源码分析

在vue3中,维护了一个全局的targetMap WeakMap实例对象,用于存储响应式对象与依赖的映射关系。

const targetMap = new WeakMap();

track方法

track方法收集依赖就是往变量targetMap中添加相关元素,存储响应式对象与依赖的映射关系。

track的源码实现如下:

function track(target, type, key) {if (shouldTrack && activeSub) {let depsMap = targetMap.get(target);if (!depsMap) {targetMap.set(target, depsMap = new Map());}let dep = depsMap.get(key);if (!dep) {depsMap.set(key, dep = new Dep());dep.map = depsMap;dep.key = key;}dep.track();}
}

这里暂且不论shouldTrackactiveSub,假定满足track的条件。首先从targetMap中读取depsMap,若depsMap中不存在,则创建一个新的Map的实例,并将其赋值给depsMap,并且存储到targetMap中。然后从depsMap中获取key对应的依赖关系dep,同理,若dep不存在,则创建一个新的Dep实例,并将其赋值给dep,并且存储到depsMap中,然后将depmapkey分别绑定depsMapkey。最后调用dep.track()方法。

dep.track()执行后,会将当前的activeSub添加到depsubs数组中。

trigger方法

track方法的源码实现如下:

function trigger(target, type, key, newValue, oldValue, oldTarget) {const depsMap = targetMap.get(target);if (!depsMap) {globalVersion++;return;}const run = (dep) => {if (dep) {dep.trigger();}};startBatch();if (type === "clear") {depsMap.forEach(run);} else {const targetIsArray = isArray(target);const isArrayIndex = targetIsArray && isIntegerKey(key);if (targetIsArray && key === "length") {const newLength = Number(newValue);depsMap.forEach((dep, key2) => {if (key2 === "length" || key2 === ARRAY_ITERATE_KEY || !isSymbol(key2) && key2 >= newLength) {run(dep);}});} else {if (key !== void 0 || depsMap.has(void 0)) {run(depsMap.get(key));}if (isArrayIndex) {run(depsMap.get(ARRAY_ITERATE_KEY));}switch (type) {case "add":if (!targetIsArray) {run(depsMap.get(ITERATE_KEY));if (isMap(target)) {run(depsMap.get(MAP_KEY_ITERATE_KEY));}} else if (isArrayIndex) {run(depsMap.get("length"));}break;case "delete":if (!targetIsArray) {run(depsMap.get(ITERATE_KEY));if (isMap(target)) {run(depsMap.get(MAP_KEY_ITERATE_KEY));}}break;case "set":if (isMap(target)) {run(depsMap.get(ITERATE_KEY));}break;}}}endBatch();
}

trigger方法在响应式数据发生变化后会被触发,vue3会先判断全局响应式集合对象targetMap中是否存在依赖对象depsMap,即是否有被追踪依赖,若不存在,则将globalVersion1,然后直接返回,没有下一步;定义run方法;调用startBatch方法,表示要进行批处理。判断type是否clear,是,则遍历依赖对象depsMap,执行run方法;否则判断target是否是数组,以及key是否数组的索引,然后根据typekey取出响应式数据对应的具体依赖,调用run方法;最后调用endBatch方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922007.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922007.shtml
英文地址,请注明出处:http://en.pswp.cn/news/922007.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VRRP 多节点工作原理

VRRP 多节点工作原理 基本概念 VRRP 的设计初衷是给一组节点提供一个 虚拟路由器,对外只表现出一个 VIP。协议规定:同一个 VRRP 实例 下始终只有 一个 Master 持有 VIP,其它全部是 Backup。 Master → 持有 VIP,负责转发流量到Mas…

Gradio全解11——Streaming:流式传输的视频应用(9)——使用FastRTC+Gemini创建沉浸式音频+视频的艺术评论家

Gradio全解11——Streaming:流式传输的视频应用(9)——使用FastRTCGemini创建沉浸式音频视频的艺术评论家11.9 使用FastRTCGemini创建实时沉浸式音频视频的艺术评论家11.9.1 准备工作及音频图像编码器1. 项目说明及准备工作2. 音频和图像编码…

Django入门笔记

Python知识点:函数、面向对象。前端开发:HTML、CSS、JavaScript、jQuery、BootStrap。MySQL数据库。Python的Web框架:Flask,自身短小精悍 第三方组件。Django,内部已集成了很多组件 第三方组件。【主要】1.安装djang…

当Claude Code失灵,Qwen Code能否成为你的救星?

当Claude Code失灵,Qwen Code能否成为你的救星? 一、开头:点明困境,引出主角 作为一个大模型博主,日常工作中我经常会使用各种 AI 工具来提高效率,Claude Code 就是我之前非常依赖的一款代码生成助手 。它…

Go语言快速入门教程(JAVA转go)——1 概述

优势 第一个理由:对初学者足够友善,能够快速上手。 业界都公认:Go 是一种非常简单的语言。Go 的设计者们在发布 Go 1.0 版本和兼容性规范后,似乎就把主要精力放在精心打磨 Go 的实现、改进语言周边工具链,还有提升 Go …

【Rust多进程】征服CPU的艺术:Rust多进程实战指南

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

OpenCV 高阶实战:图像直方图与掩码图像深度解析

目录 一、图像直方图:读懂图像的 “像素分布报告” 1. 什么是图像直方图? 2. 图像直方图的核心作用 (1)分析亮度分布 (2)判断对比度高低 (3)辅助图像增强与阈值分割 &#xf…

基于stm32的家庭安全监测系统设计

若该文为原创文章,转载请注明原文出处。一、引言(一)研究背景及意义背景:随着智能家居概念的普及,人们对家庭安全、舒适度和节能提出了更高要求。传统安防系统功能单一、各系统独立,缺乏联动和远程管理能力…

Oracle体系结构-控制文件(Control Files)

一、 原理 (Principle) 核心定位: 控制文件是一个小型的二进制文件,由 Oracle 实例在启动和操作过程中持续读写。它是数据库物理结构的权威记录。数据库无法启动或正常操作时,如果无法访问控制文件,实例将无法识别数据文件和重做日…

路由 下一跳 网关 两个不同网段的ip如何通过路由器互通

路由 (Routing)核心思想:路径选择是什么? 路由是指数据包从源主机传输到目标主机的整个过程。这个过程就像寄快递:你需要决定包裹经过哪些中转站才能最终到达收件人手里。做什么? 网络中的设备(主要是路由器&#xff0…

HiDDeN论文解读与代码实现

论文:HiDDeN: Hiding Data With Deep Networks 作者:Jiren Zhu, Russell Kaplan, Justin Johnson, Li Fei-Fei一、研究背景 在图像信息隐藏领域,通常有两类典型的应用场景:隐写 (Steganography) 目标:实现秘密通信。要…

实验室服务器配置|实验室多人共享GPU|通过Docker实现Linux系统多用户隔离与安全防控

利用实验室服务器跑实验的时候,通常就是两种方案,一个是向日葵远程桌面进行操作,一个是通过ssh进行连接,用ssh的话,一般服务器都在内网(例如校园网),是无法在公网(不在校…

2019考研数学(二)真题

一、选择题 (1) (2) (3) (4) 遗漏点:由通解知特解,特解代入微分方程 (5) ★记住这个题,用的泰勒展开(6) (7) 遗忘点: ★伴随矩阵的秩与原矩阵秩的关系: (8) 错误点:粗心 二、填空题 (9) 易混淆点&#xff…

10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑之旅

10 分钟上手 ECharts:从“能跑”到“生产级”的完整踩坑笔记 如果你也曾 复制了官方 Demo 却不知道怎么拆、窗口一拉伸图表就变形、切换标签页后内存暴涨——这篇博客就是为你写的。 我会用 6 个递进版本 的源码,带你把一张 最简柱状图 逐步进化成 可销毁…

二级缓存在实际项目中的应用

二级缓存在项目中的应用 目录 1. 二级缓存简介2. 应用场景3. 重难点分析4. 结合SpringBoot使用5. 最佳实践与案例6. 总结 1. 二级缓存简介 1.1 什么是二级缓存 二级缓存(Second-Level Cache) 是Hibernate框架中的一个重要特性,它提供了应…

深入浅出CRC校验:从数学原理到单周期硬件实现 (2)CRC数学多项式基础

数学的优雅:剖开CRC的多项式除法核心看似复杂的CRC校验,其核心建立在优雅的数学基础之上。本文将为您揭开CRC算法的数学面纱,让您真正理解多项式除法的精妙之处。模2运算:CRC世界的特殊算术 CRC计算建立在一种特殊的代数系统上——…

软考初级有没有必要考?

对正在学习相关专业的学生或者是行业新人,这篇文章从软考初级的含义、适合哪些人考、考试难度等方面解答,帮助你判断要不要报考。一、软考初级是什么? 软考初级是软考体系里面的基础级别,主要面向在校大学生或是IT行业新人&#x…

11 Prompt 工程进阶:Few-shot 与 Chain-of-Thought

11 Prompt 工程进阶:Few-shot 与 Chain-of-Thought 前10节总结 & 后10节展望 在前 10 节,我们已经完成了 AI 产品经理的入门阶段: 1–3:理解了大模型的基本概念、Token、Prompt 基础;4–5:体验了本地部…

ARM1.(ARM体系结构)

1.基本概念嵌入式:以应用为心,以计算机技术为础,软便件可被的专用计算机系统。计算机系统的软件基本组成: 系统软件、应用软件。计算机系统的硬件基本组成:运算器、控制器、存诸器、输入设备、输出设备日常生活中遇到的专业术语&#xff1a…

Django全栈班v1.01 Python简介与特点 20250910

从零开始的Python编程之旅 “人生苦短,我用Python。”这不仅仅是Python程序员的口头禅,更是对Python强大能力的最好诠释!!! 为什么全世界有超过1500万开发者选择Python? 为什么Python连续多年蝉联最受欢…