vue2雙向綁定解析

Vue 2 的雙向綁定原理基于?Object.defineProperty,核心源碼在?src/core/observer?目錄中。

1. 核心模塊:observer

observer?模塊負責將普通對象轉換為響應式對象,主要包括以下文件:

  • index.js:定義?Observer?類,用于將對象轉換為響應式。
  • dep.js:定義?Dep?類,用于管理依賴(訂閱者)。
  • watcher.js:定義?Watcher?類,用于監聽數據變化并觸發更新。

2.?Observer?類

Observer?類是 Vue 2 響應式系統的核心,它通過?Object.defineProperty?將對象的屬性轉換為?getter?和?setter,從而實現依賴收集和派發更新。

源碼位置:src/core/observer/index.js

export class Observer {value: any;dep: Dep;vmCount: number;constructor(value: any) {this.value = value;this.dep = new Dep();this.vmCount = 0;def(value, '__ob__', this); // 將 Observer 實例掛載到對象的 __ob__ 屬性上if (Array.isArray(value)) {// 處理數組if (hasProto) {protoAugment(value, arrayMethods);} else {copyAugment(value, arrayMethods, arrayKeys);}this.observeArray(value);} else {// 處理對象this.walk(value);}}walk(obj: Object) {const keys = Object.keys(obj);for (let i = 0; i < keys.length; i++) {defineReactive(obj, keys[i]);}}observeArray(items: Array<any>) {for (let i = 0, l = items.length; i < l; i++) {observe(items[i]);}}
}
  • Observer?類會遞歸地將對象的屬性轉換為響應式。
  • 對于數組,Vue 2 通過重寫數組的變異方法(如?pushpop?等)來實現響應式。

3.?defineReactive?函數

defineReactive?是 Vue 2 實現響應式的核心函數,它通過?Object.defineProperty?定義屬性的?getter?和?setter

源碼位置:src/core/observer/index.js

export function defineReactive(obj: Object,key: string,val: any,customSetter?: ?Function,shallow?: boolean
) {const dep = new Dep(); // 每個屬性都有一個 Dep 實例,用于管理依賴const getter = property && property.get;const setter = property && property.set;if ((!getter || setter) && arguments.length === 2) {val = obj[key];}let childOb = !shallow && observe(val); // 遞歸處理嵌套對象Object.defineProperty(obj, key, {enumerable: true,configurable: true,get: function reactiveGetter() {const value = getter ? getter.call(obj) : val;if (Dep.target) {dep.depend(); // 收集依賴if (childOb) {childOb.dep.depend();if (Array.isArray(value)) {dependArray(value);}}}return value;},set: function reactiveSetter(newVal) {const value = getter ? getter.call(obj) : val;if (newVal === value || (newVal !== newVal && value !== value)) {return;}if (setter) {setter.call(obj, newVal);} else {val = newVal;}childOb = !shallow && observe(newVal); // 對新值進行響應式處理dep.notify(); // 通知依賴更新},});
}
  • getter:在訪問屬性時,調用?dep.depend()?收集依賴。
  • setter:在修改屬性時,調用?dep.notify()?通知依賴更新。

4.?Dep?類

Dep?類是依賴管理器,用于存儲和管理?Watcher?實例。

源碼位置:src/core/observer/dep.js

export default class Dep {static target: ?Watcher;id: number;subs: Array<Watcher>;constructor() {this.id = uid++;this.subs = [];}addSub(sub: Watcher) {this.subs.push(sub);}removeSub(sub: Watcher) {remove(this.subs, sub);}depend() {if (Dep.target) {Dep.target.addDep(this);}}notify() {const subs = this.subs.slice();for (let i = 0, l = subs.length; i < l; i++) {subs[i].update();}}
}
  • Dep.target:當前正在計算的?Watcher?實例。
  • subs:存儲所有訂閱了該屬性的?Watcher?實例。
  • notify:通知所有訂閱者更新。

5.?Watcher?類

Watcher?類是 Vue 2 中用于監聽數據變化的訂閱者,它會在數據變化時觸發回調函數。

源碼位置:src/core/observer/watcher.js

export default class Watcher {vm: Component;expression: string;cb: Function;id: number;deps: Array<Dep>;newDeps: Array<Dep>;depIds: SimpleSet;newDepIds: SimpleSet;getter: Function;value: any;constructor(vm: Component,expOrFn: string | Function,cb: Function,options?: ?Object,isRenderWatcher?: boolean) {this.vm = vm;this.cb = cb;this.id = ++uid; // uid for batchingthis.deps = [];this.newDeps = [];this.depIds = new Set();this.newDepIds = new Set();this.getter = parsePath(expOrFn);this.value = this.get();}get() {pushTarget(this); // 將當前 Watcher 設置為 Dep.targetlet value;const vm = this.vm;try {value = this.getter.call(vm, vm);} catch (e) {// 處理錯誤} finally {popTarget(); // 恢復之前的 Watcherthis.cleanupDeps();}return value;}update() {queueWatcher(this); // 將 Watcher 加入隊列,等待批量更新}run() {const value = this.get();if (value !== this.value || isObject(value)) {const oldValue = this.value;this.value = value;this.cb.call(this.vm, value, oldValue); // 執行回調}}
}
  • Watcher?實例會在初始化時調用?get?方法,觸發屬性的?getter,從而收集依賴。
  • 當數據變化時,Watcher?的?update?方法會被調用,最終觸發回調函數。

Vue 2 的雙向綁定原理基于?Object.defineProperty,通過以下步驟實現:

  1. 響應式化Observer?類將對象的屬性轉換為?getter?和?setter
  2. 依賴收集:在?getter?中調用?dep.depend(),將當前?Watcher?添加到依賴列表中。
  3. 派發更新:在?setter?中調用?dep.notify(),通知所有依賴的?Watcher?更新。
  4. 批量更新Watcher?的更新會被加入隊列,異步執行,以提高性能。

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

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

相關文章

中級軟件設計師2004-2024軟考真題合集下載

中級軟件設計師2004-2024軟考真題合集下載 &#x1f31f; 資源亮點&#x1f3af; 適用人群&#x1f4a1; 資源使用指南&#x1f4cc; 資源獲取方式 &#x1f31f; 資源亮點 「中級軟件設計師歷年真題及答案解析&#xff08;2004-2024&#xff09;」 是全網最全、最新的備考資料…

艾爾登復刻Ep1——客戶端制作、場景切換、網絡控制

需要添加的插件內容 Netcode for GameObjects&#xff1a;是一個為 Unity 游戲開發提供高級網絡功能的 SDK。它的主要作用是允許開發者在其 GameObject 和 MonoBehaviour 工作流中集成網絡功能&#xff0c;并且可以與多種底層傳輸層協議兼容。 具體內容請看&#xff1a;https:…

2025探索短劇行業新可能報告40+份匯總解讀|附PDF下載

原文鏈接&#xff1a;https://tecdat.cn/?p41043 近年來&#xff0c;短劇以其緊湊的劇情、碎片化的觀看體驗&#xff0c;迅速吸引了大量用戶。百度作為互聯網巨頭&#xff0c;在短劇領域積極布局。從早期建立行業專屬模型冷啟動&#xff0c;到如今構建完整的商業生態&#xf…

正常的一個編碼器的架構是怎么樣,有哪些模塊構成

正常的一個編碼器架構及其模塊構成 在音視頻編碼器&#xff08;Video Encoder&#xff09;中&#xff0c;通常包括多個核心模塊&#xff0c;整個編碼器架構遵循 輸入 -> 預處理 -> 編碼核心 -> 碼流封裝 的流程。 1. 編碼器的整體架構 編碼器的主要架構如下&#xf…

文件解析漏洞練習

iis6的目錄解析漏洞 (.asp目錄中的所有文件都會被當做asp文件執行) 1.在iis的網站根目錄新建一個名為x.asp的文件 2.在x.asp中新建一個jpg文件。內容為<%now()%> asp代碼。 3.在外部瀏覽器中訪問windows2003的iis網站中的2.jpg 發現asp代碼被執行 iis6的分號截斷解析漏洞…

SQL Server性能優化實戰:從瓶頸定位到高效調優

引言 在數據庫應用中,性能問題直接影響用戶體驗和系統穩定性。本文基于實際案例,分享SQL Server性能優化的關鍵步驟與實用技巧,涵蓋問題定位、索引優化、查詢調優等多個維度。 目錄 引言 一、性能瓶頸定位 1.1 監控工具使用 二、索引優化實戰 2.1 索引碎片整理 2.2 缺…

【DNS系列】使用TCP傳輸

DNS ?默認使用UDP協議?&#xff08;端口53&#xff09;進行通信&#xff0c;但在以下場景中會切換到TCP協議?&#xff08;端口53&#xff09;&#xff1a; ?1. 響應數據過大&#xff08;超過512字節&#xff09;? ?UDP限制&#xff1a;DNS的UDP協議默認限制單個數據包大…

Go Ebiten小游戲開發:俄羅斯方塊

在這篇文章中&#xff0c;我們將一起開發一個簡單的俄羅斯方塊游戲&#xff0c;使用Go語言和Ebiten游戲庫。Ebiten是一個輕量級的游戲庫&#xff0c;適合快速開發2D游戲。我們將逐步構建游戲的基本功能&#xff0c;包括游戲邏輯、圖形繪制和用戶輸入處理。 項目結構 我們的項…

MySQL中IN關鍵字與EXIST關鍵字的比較

文章目錄 **功能等價性分析****執行計劃分析**&#xff1a; **1. EXISTS 的工作原理****步驟拆解**&#xff1a; **2. 為什么需要“利用索引快速定位”&#xff1f;****索引作用示例**&#xff1a; **3. 與 IN 子查詢的對比****IN 的工作方式**&#xff1a;**關鍵差異**&#x…

## DeepSeek寫水果記憶配對手機小游戲

DeepSeek寫水果記憶配對手機小游戲 提問 根據提的要求&#xff0c;讓DeepSeek整理的需求&#xff0c;進行提問&#xff0c;內容如下&#xff1a; 請生成一個包含以下功能的可運行移動端水果記憶配對小游戲H5文件&#xff1a; 要求 可以重新開始游戲 可以暫停游戲 卡片里的水果…

【含文檔+PPT+源碼】基于Django框架的鄉村綠色農產品交易平臺的設計與實現

項目介紹 本課程演示的是一款基于Django框架的鄉村綠色農產品交易平臺的設計與實現&#xff0c;主要針對計算機相關專業的正在做畢設的學生與需要項目實戰練習的 Python學習者。 1.包含&#xff1a;項目源碼、項目文檔、數據庫腳本、軟件工具等所有資料 2.帶你從零開始部署運…

idea超級AI插件,讓 AI 為 Java 工程師

引言? 用戶可在界面中直接通過輸入自然語言的形式描述接口的需求&#xff0c;系統通過輸入的需求自動分析關鍵的功能點有哪些&#xff0c;并對不確定方案的需求提供多種選擇&#xff0c;以及對需求上下文進行補充&#xff0c;用戶修改確定需求后&#xff0c;系統會根據需求設…

@RestControllerAdvice注解

RestControllerAdvice RestControllerAdvice 是 Spring Framework&#xff08;3.2&#xff09;和 Spring Boot 中用于全局處理控制器層異常和統一響應格式的注解。它結合了 ControllerAdvice 和 ResponseBody 的功能&#xff0c;能夠攔截控制器方法拋出的異常&#xff0c;并以 …

ActiveMQ監聽器在MQ重啟后不再監聽問題

應用的監聽器注解 JmsListener(destination "TopicName",containerFactory "FactoryName")工廠代碼 BeanJmsListenerContainerFactory<?> FactoryName(ConnectionFactory connectionFactory){SimpleJmsListenerContainerFactory factory new S…

大白話 Vue 中的keep - alive組件,它的作用是什么?在什么場景下使用?

大白話 Vue 中的keep - alive組件&#xff0c;它的作用是什么&#xff1f;在什么場景下使用&#xff1f; 什么是 keep-alive 組件 在 Vue 里&#xff0c;keep-alive 是一個內置組件&#xff0c;它就像是一個“保存盒”&#xff0c;能把組件實例保存起來&#xff0c;而不是每次…

考研復試c語言常見問答題匯總2

11. 關鍵字和一般標識符有什么不同&#xff1f; C語言中關鍵字與一般標識符區別&#xff1a; 定義&#xff1a;關鍵字是C語言預定義的特殊單詞&#xff08;如int、for&#xff09;&#xff0c;有固定含義&#xff1b;標識符是自定義的名稱&#xff08;如變量名、函數名&#xf…

Scala編程_實現Rational的基本操作

在Scala中實現一個簡單的有理數&#xff08;Rational&#xff09;類&#xff0c;并對其進行加法、比較等基本操作. 有理數的定義 有理數是可以表示為兩個整數的比值的數&#xff0c;通常形式為 n / d&#xff0c;其中 n 是分子&#xff0c;d 是分母。為了確保我們的有理數始終…

若依框架-給sys_user表添加新字段并獲取當前登錄用戶的該字段值

目錄 添加字段 修改SysUser類 修改SysUserMapper.xml 修改user.js 前端獲取字段值 添加字段 若依框架的sys_user表是沒有age字段的&#xff0c;但由于業務需求&#xff0c;我需要新添加一個age字段&#xff1a; 修改SysUser類 添加age字段后&#xff0c;要在SysUser類 …

霍夫變換法是基于傳統視覺特征的道路車道線檢測算法中的一種經典方法

霍夫變換法是基于傳統視覺特征的道路車道線檢測算法中的一種經典方法&#xff0c;以下是對它的詳細介紹&#xff1a; 基本原理 霍夫變換的基本思想是將圖像空間中的點映射到參數空間中&#xff0c;通過在參數空間中尋找峰值來確定圖像中特定形狀的參數。在車道線檢測中&#…

【論文筆記】Best Practices and Lessons Learned on Synthetic Data for Language Models

論文信息 論文標題&#xff1a;Best Practices and Lessons Learned on Synthetic Data for Language Models 作者信息&#xff1a; Ruibo Liu, Jerry Wei, Fangyu Liu, Chenglei Si, Yanzhe Zhang, Jinmeng Rao, Steven Zheng, Daiyi Peng, Diyi Yang, Denny Zhou1 and Andre…