vue 的響應(yīng)式系統(tǒng)通過依賴追蹤實(shí)現(xiàn)自動(dòng)更新視圖。1. 數(shù)據(jù)劫持:vue 2 使用 Object.defineproperty,vue 3 使用 proxy,使數(shù)據(jù)在被訪問或修改時(shí)可被觀測(cè);2. 依賴收集:當(dāng)數(shù)據(jù)被讀取時(shí),如在模板中使用 {{ message }},當(dāng)前 watcher 會(huì)被記錄到該數(shù)據(jù)的依賴列表中;3. 派發(fā)更新:數(shù)據(jù)變化時(shí)觸發(fā) setter 或 proxy 的 set,通知所有依賴的 watcher 異步批量更新。此外,數(shù)組需用變異方法更新,新增屬性需用 vue.set,深層響應(yīng)則通過遞歸實(shí)現(xiàn)。掌握這三步機(jī)制,便能理解 vue 響應(yīng)式系統(tǒng)的核心原理。
Vue 的響應(yīng)式系統(tǒng)之所以能自動(dòng)更新視圖,關(guān)鍵就在于它能夠追蹤依賴。簡單來說,當(dāng)數(shù)據(jù)變化時(shí),Vue 能知道哪些組件或計(jì)算屬性需要重新渲染,這背后靠的就是依賴追蹤機(jī)制。
那它是怎么做到的呢?我們來分幾個(gè)角度看看。
數(shù)據(jù)劫持:讓數(shù)據(jù)“可觀測(cè)”
Vue 2 和 Vue 3 在實(shí)現(xiàn)上略有不同,但核心思想是一樣的:對(duì)數(shù)據(jù)進(jìn)行劫持,使其在被訪問或修改時(shí)可以觸發(fā)一些行為。
立即學(xué)習(xí)“前端免費(fèi)學(xué)習(xí)筆記(深入)”;
- 在 Vue 2 中,使用的是 Object.defineProperty 來監(jiān)聽對(duì)象屬性的變化。
- 在 Vue 3 中,使用了更現(xiàn)代的 Proxy,可以監(jiān)聽整個(gè)對(duì)象的操作,而不僅僅是某個(gè)屬性。
一旦數(shù)據(jù)被訪問(比如模板里用了 {{ message }}),Vue 就會(huì)記錄下這個(gè)“誰”用到了這個(gè)數(shù)據(jù),也就是建立一個(gè)依賴關(guān)系。
依賴收集:誰用了我?
依賴收集的過程其實(shí)就是在讀取數(shù)據(jù)的時(shí)候,把當(dāng)前正在執(zhí)行的 watcher(觀察者)記錄下來。
舉個(gè)例子:
data() { return { message: 'Hello Vue' } }
當(dāng)組件渲染時(shí),它會(huì)訪問 message,這時(shí)候 Vue 就知道:“哦,這個(gè)組件用到了 message”,于是把這個(gè)組件對(duì)應(yīng)的 watcher 加入到 message 的依賴列表中。
你可以把它想象成這樣:
- 每個(gè)數(shù)據(jù)都有一個(gè)“小本本”,上面記著誰用過我。
- 當(dāng)數(shù)據(jù)變了,就告訴這些“用過我的人”:“我變了,你該更新了。”
派發(fā)更新:數(shù)據(jù)變了,通知訂閱者
當(dāng)你修改了響應(yīng)式數(shù)據(jù),比如:
this.message = 'New Message'
這時(shí)候 Vue 會(huì)觸發(fā)數(shù)據(jù)的 setter(或者 Proxy 的 set 攔截),然后去遍歷之前收集到的依賴,一個(gè)個(gè)通知它們更新。
這個(gè)過程就是“派發(fā)更新”。
注意幾點(diǎn):
- 更新不是立即執(zhí)行的,而是異步批量處理的,這樣可以避免頻繁重渲染。
- 計(jì)算屬性、watch、組件模板里的變量都會(huì)形成不同的 watcher,并各自管理自己的依賴。
一些容易忽略的細(xì)節(jié)
- 數(shù)組的響應(yīng)式處理有點(diǎn)特殊:Vue 不能直接通過索引修改數(shù)組元素來觸發(fā)更新,必須使用變異方法(如 push、splice)或用 Vue.set。
- 新增屬性不會(huì)自動(dòng)響應(yīng):如果對(duì)象一開始沒有定義某個(gè)屬性,后面再加進(jìn)去,是不會(huì)被追蹤的。可以用 Vue.set 或 this.$set 解決。
- 深層響應(yīng)是遞歸完成的:如果你的數(shù)據(jù)嵌套很深,Vue 會(huì)在初始化時(shí)遞歸地把所有子屬性也變成響應(yīng)式的。
基本上就這些。理解依賴追蹤的核心邏輯后,你會(huì)發(fā)現(xiàn) Vue 的響應(yīng)式系統(tǒng)雖然強(qiáng)大,但并不神秘。只要記住三點(diǎn):數(shù)據(jù)劫持 → 依賴收集 → 派發(fā)更新,就能掌握它的運(yùn)作方式。