Vue3 响应式核心源码全解析:Dep、Link 与 track/trigger 完整执行机制详解

作者:excel日期:2025/10/8

逐行解读

Vue3 的响应式系统是整个框架的灵魂,它让开发者能够在不显式调用更新的情况下自动响应数据变化。本文将带你深入阅读 Vue3 的核心响应式模块源码,重点讲解 DepLinktracktrigger 等关键机制,并用通俗的语言串联其工作流程,让你真正理解 Vue3 响应式系统的运行原理。


一、响应式系统的设计思路

Vue3 的响应式系统基于 依赖收集(track)派发更新(trigger) 两大过程:

  • track:在读取响应式数据时记录依赖,建立「谁依赖了谁」的关系;
  • trigger:当依赖的数据发生变化时,通知对应的副作用函数(effect)重新执行。

核心问题是:如何高效、准确地追踪依赖关系并在更新时精准触发?

Vue3 使用 Dep(依赖容器)和 Link(依赖连接)这两个类,配合 targetMap(全局依赖映射表),构建出一个双向的依赖追踪结构。


二、Dep:依赖容器

Dep 是每个响应式属性的依赖中心,负责维护所有订阅它的副作用函数。

1export class Dep {
2  version = 0
3  activeLink?: Link
4  subs?: Link
5  subsHead?: Link
6  sc: number = 0
7
8  constructor(public computed?: ComputedRefImpl | undefined) {}
9}
10

主要属性:

  • version:当前依赖的版本号,每次触发时递增;
  • subs / subsHead:双向链表,记录所有订阅者(副作用函数);
  • activeLink:当前活跃的依赖连接;
  • sc:订阅者数量计数。

Dep 是响应式系统的“核心神经节点”,它知道有哪些副作用依赖自己,也能在变化时精确通知它们。


三、Link:Dep 与 Effect 的连接纽带

DepEffect(副作用函数)是多对多关系。
Link 就是这两者之间的桥梁,用于在它们之间建立和维护依赖。

1export class Link {
2  version: number
3  nextDep?: Link
4  prevDep?: Link
5  nextSub?: Link
6  prevSub?: Link
7
8  constructor(public sub: Subscriber, public dep: Dep) {
9    this.version = dep.version
10  }
11}
12

可以理解为:

  • 每个 Link 同时存在于两条链表中:
    • 一条属于 Effect,记录它依赖的所有 Dep
    • 一条属于 Dep,记录它的所有订阅者。
  • Effect 执行时,Link 会根据访问的属性动态更新依赖关系。

这种 双向链表结构 能快速定位和清理依赖,避免重复依赖和内存泄漏。


四、track:依赖收集

track() 是读取响应式属性时调用的核心函数。它的任务是:
在读取属性时记录当前活跃的副作用函数(activeSub),让它与属性对应的 Dep 建立联系。

1export function track(target: object, type: TrackOpTypes, key: unknown): void {
2  if (shouldTrack && activeSub) {
3    let depsMap = targetMap.get(target)
4    if (!depsMap) {
5      targetMap.set(target, (depsMap = new Map()))
6    }
7    let dep = depsMap.get(key)
8    if (!dep) {
9      depsMap.set(key, (dep = new Dep()))
10      dep.map = depsMap
11      dep.key = key
12    }
13    dep.track({ target, type, key })
14  }
15}
16

执行流程如下:

  1. 查找当前对象在 targetMap 中的依赖映射;
  2. 如果没有就创建一个新的;
  3. 获取对应 key 的 Dep
  4. 调用 dep.track() 将当前的 activeSub(副作用函数)与此属性关联。

简单来说,track() 就是在“我读取了这个属性”时,登记“我依赖它”。


五、trigger:派发更新

trigger() 是响应式系统的另一端,它在属性修改时触发依赖更新。

1export function trigger(target, type, key?, newValue?, oldValue?) {
2  const depsMap = targetMap.get(target)
3  if (!depsMap) {
4    globalVersion++
5    return
6  }
7
8  const run = (dep: Dep | undefined) => dep && dep.trigger()
9
10  if (type === TriggerOpTypes.CLEAR) {
11    depsMap.forEach(run)
12  } else {
13    const targetIsArray = isArray(target)
14    const isArrayIndex = targetIsArray && isIntegerKey(key)
15
16    if (targetIsArray && key === 'length') {
17      // 数组长度变化时触发相关依赖
18      const newLength = Number(newValue)
19      depsMap.forEach((dep, key) => {
20        if (key === 'length' || key >= newLength) run(dep)
21      })
22    } else {
23      run(depsMap.get(key))
24      if (isArrayIndex) run(depsMap.get(ARRAY_ITERATE_KEY))
25      switch (type) {
26        case TriggerOpTypes.ADD:
27          run(depsMap.get(ITERATE_KEY))
28          break
29        case TriggerOpTypes.DELETE:
30          run(depsMap.get(ITERATE_KEY))
31          break
32      }
33    }
34  }
35}
36

核心思路:

  • 修改属性 → 找到对应的 Dep
  • 调用 dep.trigger() 通知所有订阅者;
  • 依赖对应的 Effect(或 Computed)重新执行。

Vue3 针对不同类型(对象、数组、Map、Set)做了细致优化,比如:

  • 数组修改 length 会触发超出新长度的索引依赖;
  • Map 的 ADDDELETE 会额外触发迭代器依赖。

六、globalVersion 与批处理机制

每次响应式变更都会触发:

1globalVersion++
2

它用于快速判断计算属性(computed)是否需要重新计算。

此外,Vue3 在触发更新时通过 startBatch()endBatch() 包裹通知过程,实现了批量触发、延迟执行,从而显著减少重复计算和性能浪费。


七、依赖结构图示

为了更直观地理解整个机制,可以把依赖关系抽象为如下结构:

1Reactive Target
2   └── key -> Dep
3            ├── Link -> Effect A
4            ├── Link -> Computed B
5            └── Link -> Effect C
6
  • track():在访问属性时建立这些箭头;
  • trigger():当属性变化时,沿箭头依次通知所有订阅者。

八、总结

Vue3 的响应式系统在性能和结构上都做了精细设计:

  • 使用 Dep 管理依赖;
  • Link 构建高效的双向链表;
  • 借助 targetMap 构建全局依赖关系;
  • 通过 tracktrigger 完成依赖收集与派发更新;
  • 引入 globalVersion 与批处理优化机制,避免多余计算。

当你理解了这些底层逻辑,再回头看 Vue 的 reactive()computed()watch() 等 API,就会发现——它们都是基于这套机制自然生长出来的。


本文内容由人工智能生成,仅供学习与参考使用,请在实际应用中结合自身情况进行判断。


Vue3 响应式核心源码全解析:Dep、Link 与 track/trigger 完整执行机制详解》 是转载文章,点击查看原文


相关推荐


JMeter接口测试
鱼鱼说测试2025/10/7

1小时postman接口测试从入门到精通教程 1、创建测试任务 添加线程组,右击测试计划,在快捷菜单单击添加-》线程(用户)-》线程组。设置线程组主要包含三个参数:线程数、Ramp-Up、循环次数。 线程数:设置虚拟用户数。一个虚拟用户占用一个进程或线程。线程数就相当于虚拟用户数。 Ramp-Up:设置的线程数启动时长,单位为秒。如果线程数为100,准备时长为20秒,那么需要20秒启动100个线程,平均每秒启动5个线程。 循环次数:每个线程发送请求的个数。如果线程数为100,


Windows 环境下安装 Node.js 和 Vue.js 框架完全指南
做运维的阿瑞2025/10/5

本指南将引导你完成在 Windows 操作系统上安装 Node.js、配置 npm 以及安装 Vue.js 框架的全过程。无论你是前端开发新手还是想要搭建本地开发环境的开发者,这篇文章都将为你提供详细的步骤指导和实用技巧。 文章目录 🎯 1. 整体流程概览📦 2. 环境准备与系统要求2.1 系统要求2.2 预备知识 🔧 3. 安装 Node.js3.1 版本选择策略3.2 下载安装包3.3 图形化安装步骤验证安装 ⚡ 4. npm 包管理器配置与优化4.1 npm 基


某大厂库存秒杀的设计与实现总结
360_go_php2025/10/4

​ 在面试中,阿里这类大公司的技术面试中,关于高并发场景下的秒杀系统是一个常见的考察点。秒杀系统的核心目标是在大量用户同时请求某一商品时,如何高效、准确地处理并发请求,避免库存超卖,并确保系统的稳定性。下面将详细介绍阿里库存秒杀系统的实现原理和常用技术。​编辑 1. 秒杀系统的基本需求 秒杀系统需要应对高并发请求,尤其是在商品上线后几秒钟内,可能会有成千上万的请求涌入。系统的设计不仅要保证库存的准确性,还要保证用户体验和系统的高可用性。​编辑 2. 核心问题 高并发请求:如何处理成千上万的并发


ChatGPT From Zero To Hero - LLM学习笔记(一)
ASKED_20192025/10/3

如何训练一个chatGPT from zero to hero,主要来源是Karpathy 大神的视频 一、预训练 (Pretraining) Unsupervised Training — 让模型“学会说话” Step 1: Download and preprocessing the internet 下载并清洗互联网数据 从开放语料抓取:Common Crawl、Wikipedia、Books、GitHub、StackExchange、ArXiv去重、过滤低质量和有害内容保证语料


第2章 三个小工具的编写(2)
班公湖里洗过脚2025/10/2

2.3 PEComp的实现 PEComp是PE文件比较器。功能是按照PE文件格式的数据结构按字段对两个指定的PE文件进行比对,以获取两个PE文件结构中的不相同的信息。在实际应用中,我们可以通过对比病毒感染前后PE文件在相关字段上发生的变化来判断病毒的感染方式,从而确定清理病毒的方法。 2.3.1 编程思路 PEComp的功能是在通用框架pe.asm的基础上,实现两个PE文件的对比,并通过图形界面将不同之处形象地表示出来。编码的大致思路如下: 步骤1 打开要比较的两个文件,分别进行文件的内


SpringCloudGateway:像快递分拣中心一样的API网关
ccccczy_2025/10/2

实际场景引入 想象一下双十一期间的快递分拣中心。海量包裹(用户请求)从四面八方涌来,如何高效、准确地将它们分发到全国各地的配送站(微服务)?这正是Spring Cloud Gateway要解决的问题——作为微服务架构的“总入口”,它负责接收所有外部请求,并根据规则进行路由、过滤和安全控制。 深度解析:核心组件与代码示例 1. 路由(Route)—— 分拣流水线 路由是网关的基本单元,定义了请求从何而来,到哪里去。就像分拣线上的一条条通道,决定包裹的流向。 // 配置文件方式 gateway:


Mosquitto:MQTT Broker入门与分布式部署最佳实践
老坛程序员10/2/2025

本文介绍了开源MQTT代理服务器Mosquitto的核心特性、安装部署及扩展开发。Mosquitto由Eclipse基金会维护,支持MQTT 3.1/3.1.1/5.0协议,具有轻量高效、支持多种QoS等级、TLS加密等特点。文章详细说明了从GitHub源码编译安装的方法,并演示了基本的订阅发布测试。针对分布式场景,提供了多节点部署方案和Docker集群配置示例。最后介绍了如何开发自定义认证插件,通过数据库实现设备鉴权,包括插件框架设计、认证函数实现等关键技术点。全文为MQTT代理服务器的部署应用和功能扩展


多主机Docker Swarm集群网络拓扑可视化监控方案的部署规范
cpsvps_net10/1/2025

本文将从网络架构设计、监控工具选型、数据采集规范、可视化实现和安全策略五个维度,详细解析符合企业级标准的部署方案,帮助运维团队构建高可用、易维护的集群监控体系。


排序算法汇总,堆排序,归并排序,冒泡排序,插入排序
Tiny番茄9/30/2025

Code实现(使用python自带的堆进行实现)


微信小程序开发从零基础到项目发布的全流程实战教程(四)
Terio_my2025/10/10

小程序开发实战课程笔记 第一章:项目初始化与纯净环境搭建 在正式进入开发前,我们需要先创建一个干净的小程序项目环境,以便后续教学不受模板或默认配置干扰。 1.1 创建新项目 操作步骤: 打开 微信开发者工具。点击左上角「+」号或「新建项目」按钮。配置项目信息: 项目名称:demo002项目目录:选择本地存储路径AppID:填写自己的小程序 AppID(可使用测试号)项目类型:选择“小程序”不使用云服务不使用模板 ✅ 提示:务必勾选“不使用模板”,否则会自动引入 pa

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0