vue2 的資料偵測**在 `/src/observer/` 目錄裡面,元件例項在初始化時,會呼叫 `observe` 函式處理 `data`。
function initdata (vm)
`observe` 改寫了所有物件屬性的 `getter`、`setter` 和陣列原型上的 7 個會改寫陣列方法,從而讓 `data` 變成可響應的。
class observer else
}observearray (items)
}walk (obj)
}}function observe (value)
function definereactive (obj, key) }}
return value
},// 修改了響應式物件屬性值或者呼叫了響應式陣列的幾個特殊方法,都會通知對應的 `dep` 下的 `watchers` 進行更新。
set (newval)
})}function dependarray (value) }}
每個元件例項都對應乙個 `watcher` 例項(即 `dep` 收集的 `sub`),元件渲染時會將 `dep.target` 指向當前 `watcher` 例項,然後在渲染過程中把「接觸」過(`getter`)的響應式物件屬性記錄為依賴。
每個 `computed` 屬性和 `$watch` 的依賴也都對應乙個 `watcher` 例項。
dep.target.adddep(dep)
dep.addsub(watcher)
每個物件的屬性對應乙個 `dep` 例項,收集了以它為依賴的 `watchers`。
修改了響應式物件屬性值或者呼叫了響應式陣列的幾個特殊方法,都會通知對應的 `dep` 下的 `watchers` 進行更新,從而使它關聯的元件重新渲染。
for (const watcher of subs)
vue3 的資料偵測**在 `/packages/reactivity/` 目錄裡面,元件渲染時 `mountcomponent` 呼叫 `setuprendereffect`,當前的元件例項對應的 `effect` 即 `instance.update` 就成了 `activeeffect`。
當我們在這個時候使用了 `setup` 返回的用 `ref` 和 `reactive` 生成的 `proxy` 響應式資料時,`proxy` 的 `get` 函式執行時會 `track(target, 'get', key)`,在當前啟用的 `effect` 裡面記錄依賴。
dep.add(activeeffect)
activeeffect.deps.push(dep)
之後修改響應式資料時,`proxy` 的 `set` 函式呼叫 `trigger`,通知依賴關聯的 `effects` 更新。
effects.foreach(effect => effect())
`vue2` 是使用 `object.defineproperty` 跟蹤物件上的屬性,所以不能直接新增屬性而要使用 `$set`。
// this.obj ==> {}
this.obj.msg = 'hello'
// 直接修改陣列的某個索引也不會被觀測到。
this.array[0] = '100'
而 `vue3` 是使用 `proxy` 跟蹤了這個物件,即便是新增屬性,也會執行 `trigger`,不過這裡要執行的是遍歷物件 `symbol` 屬性 `iterate_key` 下的 `effects`。
執行對應 `effects` 讀取新屬性時會成功 `track`,為新屬性生成 `dep`。
陣列也是類似的道理,無論是直接修改乙個索引或者直接修改 `length` 屬性,都是可響應的。`vue3` 是在真正使用到響應式資料相關屬性時才執行響應式的相關**,而 `vue2` 是在初始化 `data` 時就遞迴處理好了資料。
Vue 響應式屬性
本文參考自 1 概述 當建立乙個vue例項時,每個資料屬性 元件屬性等都是可以遍歷的,並為每個資料屬性新增了getter和setter。getter和setter允許vue觀察資料的更改並觸發更新。如果你在vue例項化後新增 或刪除 乙個屬性 例如在方法或生命週期鉤子中 vue是不知道它的。2 更新...
vue響應式原理
響應式系統是vue框架核心的部分,資料物件僅僅是普通的 js物件。當我們改變資料時,檢視也會被改變,本文就來 一下vue 的響應式原理。vue響應式的核心是使用了es5 新增的api object.defineproperty 因此vue不支援ie8 object.defineproperty的作用...
vue響應式物件
在vue中與檢視中繫結的資料,其資料的變化會驅動檢視的更新,這是因為vue是響應式 那麼有沒有那麼一種情況資料的變化檢視沒有變化呢?答案肯定是有的,例如物件的屬性變化vue並不能監聽到,因此資料的變化並不能驅動檢視更新 vue也提供了 set方法來更新物件屬性值的變化,但是也會有奇怪的現象比如 te...