Vue 3 響應式核心源碼詳解(基于 @vue/reactivity)

🧬 Vue 3 響應式核心源碼詳解(基于 @vue/reactivity)

?? 整理不易,記得點贊、收藏、關注,揭開 Vue 響應式的神秘面紗!


🧭 一、源碼結構總覽(relevant files)

Vue 的響應式系統主要在 @vue/reactivity 包中,核心源碼文件包括:

文件名作用說明
reactive.ts創建響應式對象的入口
ref.ts實現 ref 響應式數據
effect.ts實現副作用追蹤(依賴收集與觸發)
computed.ts實現 computed 的緩存邏輯
watch.ts實現 watch 響應邏輯
baseHandlers.ts代理對象的攔截邏輯(get/set)
reactiveEffect.ts核心依賴收集機制(調度系統)

我們將通過 執行流程 + 源碼解構 + 關鍵機制 三個部分講透它👇


🔍 二、響應式系統的運行流程(大局觀)

  1. 使用 reactive(obj)ref(value) 創建響應式數據;
  2. 使用響應式數據的地方(如組件、computed)注冊為“副作用函數” ReactiveEffect
  3. 數據被訪問時會收集依賴(track);
  4. 數據被修改時會觸發依賴(trigger);
  5. 依賴更新后觸發副作用函數(如組件更新、watch 回調、computed 重算)。

🧠 本質上,是一個“數據和函數之間的訂閱-發布機制”。


🧪 三、關鍵源碼拆解


1?? reactive 的本質:Proxy 包裹對象

export function reactive(target: object): object {return createReactiveObject(target, false, mutableHandlers)
}

實際調用的是 createReactiveObject,它的核心邏輯:

function createReactiveObject(target, isReadonly, baseHandlers) {const proxy = new Proxy(target, baseHandlers)return proxy
}

配合 mutableHandlers.ts 中的 get 攔截器:

get(target, key, receiver) {const res = Reflect.get(target, key, receiver)track(target, 'get', key)  // 依賴收集return isObject(res) ? reactive(res) : res
}

📌 重點:每次讀取屬性,會調用 track() 做依賴收集!


2?? ref 的本質:包裹值 + 自定義 getter/setter

export function ref(value) {return createRef(value)
}
function createRef(rawValue) {const r = {get value() {track(r, 'get', 'value') // 收集依賴return rawValue},set value(newVal) {rawValue = newValtrigger(r, 'set', 'value') // 觸發更新}}return r
}

? ref 是通過 getter/setter 控制單值的響應式行為。


3?? track:收集依賴

const targetMap = new WeakMap()export function track(target, type, key) {if (!activeEffect) returnlet depsMap = targetMap.get(target)if (!depsMap) {depsMap = new Map()targetMap.set(target, depsMap)}let dep = depsMap.get(key)if (!dep) {dep = new Set()depsMap.set(key, dep)}dep.add(activeEffect) // 綁定副作用函數
}

每個對象的 key -> Set(effect),形成完整依賴圖。


4?? trigger:觸發依賴

export function trigger(target, type, key) {const depsMap = targetMap.get(target)if (!depsMap) returnconst effects = depsMap.get(key)if (effects) {effects.forEach(effect => {effect()})}
}

數據變了,就找到 key 對應的 effect 執行回調!


5?? ReactiveEffect 類:副作用的封裝載體

export class ReactiveEffect {constructor(fn, scheduler) {this.fn = fnthis.scheduler = scheduler}run() {activeEffect = thisreturn this.fn()}
}

用于封裝副作用函數,例如 watchcomputed、組件更新邏輯等。


6?? computed 的實現:帶緩存的 ReactiveEffect

export function computed(getter) {let valuelet dirty = trueconst effect = new ReactiveEffect(getter, () => {dirty = truetrigger(obj, 'set', 'value')})const obj = {get value() {if (dirty) {value = effect.run()dirty = false}track(obj, 'get', 'value')return value}}return obj
}
  • 懶執行:只有在 .value 被訪問時才執行
  • 緩存機制:依賴沒變不會重新執行 getter

7?? watch 的實現:注冊一個副作用函數,包裹 source

export function watch(source, cb, options?) {let getter = () => source.value // 簡化const job = () => {const newVal = effect.run()cb(newVal, oldVal)oldVal = newVal}const effect = new ReactiveEffect(getter, job)if (options.immediate) job()else oldVal = effect.run()
}
  • 自動依賴收集
  • 值變化后執行 job 調用回調

📦 四、響應式系統核心圖示總結

          +-------------------------+|     reactive/ref       |+-------------------------+|↓ Proxy or Getter|+--------------+|  track()     | ← 收集依賴+--------------+|+--------------+| trigger()    | → 執行副作用+--------------+|+---------------------------+| ReactiveEffect(fn)       |+---------------------------+↑          ↓run()       scheduler(watch/computed)

🧠 五、總結一下

機制功能說明
reactiveProxy 代理對象,攔截 get/set 實現響應式
ref定義 .value 屬性,包裹單值響應式
track收集依賴到 effect
trigger執行依賴的 effect
ReactiveEffect封裝副作用函數
computed帶緩存的懶執行響應式副作用
watch主動監聽響應式數據變化,執行回調

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912600.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912600.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912600.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

編寫shell腳本掃描工具,掃描服務器開放了哪些端口(再嘗試用python編寫一個)

先將需要掃描的服務器的端口顯示出來,然后再顯示哪些ip地址對應的服務器的哪些端口已開放或未開放 下面這個shell腳本可以同時掃描多個ip對應的多個服務器的多個端口是否開放: 以下是運行結果: nc 和 nmap 掃描別人的機器開放了哪些端口 ne…

java JNDI高版本繞過 工具介紹 自動化bypass

JNDI高版本rce失效問題 原因: 主要還是協議控制高版本的一般都會關閉如rmi,ldap等協議遠程加載的類 RMI限制: com.sun.jndi.rmi.object.trustURLCodebase、com.sun.jndi.cosnaming.object.trustURLCodebase的默認值變為false,即…

JavaWeb筆記02

三、數據庫設計 1_簡介 1.數據庫設計設計什么? 有哪些表 表里有哪些字段 表和表之間是什么關系 2.表關系有哪幾種? 一對一 一對多(多對一) 多對多 2_多表關系實現 表關系之一對多 一對多 (多對一): 如:部門表和員…

Junit_注解_枚舉

文章目錄 一:Junit單元測試測試分類:Junit的使用Before_After 二:注解什么是注解文檔相關的注解IDEA中的javadoc使用:JDK內置的3個注解自定義注解 元注解RetentionTargetRepeatableDocumented(用的很少)Inh…

將N8N配置為服務【ubuntu】

docker模式不在此討論。這里討論的是node安裝為n8n后,如何安裝為服務: 安裝NODE(略) 安裝N8N 一個命令解決: npm install n8n -g 安裝服務 vi /etc/systemd/system/n8n.service內容如下 [Unit] Descriptionn8…

Java后端調用外部接口標準流程詳解

在Java后端開發中,調用外部HTTP接口(如第三方平臺API、云服務、微服務等)是非常常見的需求。實現這個功能通常遵循一套標準的流程: 1. 準備DTO類(數據傳輸對象) 作用: DTO(Data Tra…

星火燎原 數智新生 —— 《GB/T 45341—2025》 × AI大模型 × 全域PaaS創新,領碼SPARK打造行業數字化轉型新范式

【摘要】 數字中國新征程,標準引航數智化。面對企業數字蝶變的關鍵關口,《GB/T 45341—2025 數字化轉型管理 參考架構》引領行業規范發展。愛分析最新數據顯示,中國iPaaS市場規模持續高增長,印證PaaS已成為企業數字化基石。 AI大…

25-7-1 論文學習(1)- Fractal Generative Models 何愷明大佬的論文

分形生成模型 Tianhong Li1 Qinyi Sun1 Lijie Fan2 Kaiming He1 摘要 模塊化是計算機科學的基石,它將復雜函數抽象為原子構建塊。在本文中,我們通過將生成模型抽象為原子生成模塊,引入了新的模塊化層次。類似于數學中的分形,我…

如何讀取運行jar中引用jar中的文件

1.問題發現 項目中有個common包資源文件,然后springboot項目引用了common,那么我們要怎么讀取這個資源了。這里需要考慮三個場景,idea運行時、common jar獨立運行時、springboot引用common后運行時。 2.問題解決 2.1.idea運行時 Protection…

【學習方法】框架質疑學習法:破解專業學習的“知識厚度”困境

今天博主給大家分享一個,我自己發明了一個比較高效的學習方法,名叫“框架質疑學習法” 本文提出的框架質疑學習法(Framework Questioning Learning Method)為本文作者,也就是我,董翔首次提出。 在軟件專業的學習中&a…

spring-ai 1.0.0 學習(十七)——MCP Client

之前學過了工具調用(spring-ai 1.0.0 學習(十二)——工具調用_springai 1.0 如何判斷調用哪一個tool工具-CSDN博客),今天來看一下MCP MCP是什么 MCP全稱是模型上下文協議,有點繞,通俗點理解&a…

Git 運行.sh文件

1.在項目文件中右擊 Open Git Bash here 顯示(base)環境 2.激活conda環境 3.復制.sh文件的相對路徑 4.將路徑復制到git終端 先輸入sh和空格,然后右擊后選paste,不要直接ctrl v 5.開始運行

MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么區別?

MySQL InnoDB 引擎中的聚簇索引和非聚簇索引有什么區別? 主要解答詳細解答1. **聚簇索引(Clustered Index)**2. **非聚簇索引(Non-Clustered Index / Secondary Index)**3. **對比總結**4. **流程圖(查詢過…

[2025CVPR]DE-GANs:一種高效的生成對抗網絡

目錄 引言:數據高效GAN的困境 核心原理:動態質量篩選機制 1. 判別器拒絕采樣(DRS)的再思考 2. 質量感知動態拒絕公式 (1)質量感知階段 (2)動態拒絕階段 模型架構:輕量化設計 技術突破:三大創新點 1. 首創訓練階段DRS 2. 動態拒絕機制 3. 質量重加權策略 …

[面試] 手寫題-數組轉樹

示例數據: const arr [{ id: 1, parentId: null, name: Root },{ id: 2, parentId: 1, name: Child 1 },{ id: 3, parentId: 1, name: Child 2 },{ id: 4, parentId: 2, name: Grandchild 1 }, ]目標生成: const tree [{id: 1,name: Root,children: …

CertiK《Hack3d:2025年第二季度及上半年Web3.0安全報告》(附報告全文鏈接)

CertiK《Hack3d:2025年第二季度及上半年Web3.0安全報告》現已發布,報告顯示:僅2025年上半年,因安全事件導致的損失接近25億美元;截至目前,總損失已超過去年全年水平。整體來看,Web3.0安全形勢依…

反向傳播 梯度消失

反向傳播 backpropagation 反向傳播(Backpropagation) 是神經網絡訓練中的一種核心算法,用于通過計算誤差并將其傳播回網絡,從而更新神經網絡的參數。通過反向傳播,網絡能夠在每次迭代中逐步調整其參數(例…

京東外賣服務商加入方案對比!選擇本地生活服務商系統的優勢,到底在哪?

自入局之日起,京東外賣似乎就一直熱衷于給人驚喜: 先是在上線時規定了“2025年5月1日前入駐的商家,全年免傭金”和“僅限品質堂食商家入駐”; 再是宣布了要為外賣騎手繳納五險一金,并承擔其中的所有成本;…

【RTSP從零實踐】4、使用RTP協議封裝并傳輸AAC

😁博客主頁😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客內容🤑:🍭嵌入式開發、Linux、C語言、C、數據結構、音視頻🍭 🤣本文內容🤣&a…

Bootstrap 安裝使用教程

一、Bootstrap 簡介 Bootstrap 是一個開源的前端框架,由 Twitter 開發,旨在快速開發響應式、移動優先的 Web 頁面。它包含 HTML、CSS 和 JavaScript 組件,如按鈕、導航欄、表單等。 二、Bootstrap 安裝方式 2.1 使用 CDN(推薦入…