reactive
類的 api 主要提供了將複雜類型的數據處理成響應式數據的能力,其實這個複雜類型是要在object array map set weakmap weakset
這五種之中(object 指的是 {}),在調用 reactive
類 api 處理數據時,有一個判斷以下vue
if (!canObserve(target)) {
return target
}
// 下面是 canObserver 的實現
const canObserve = (value: Target): boolean => {
return (
!value[ReactiveFlags.SKIP] && // 表示這個對象須要跳過,不能再進行 reactive 的響應式處理。好比自定義組件
isObservableType(toRawType(value)) &&
!Object.isFrozen(value) // 這個對象沒有被 Object.frozen() 處理過,被處理過的在非嚴格模式下的賦值不會報錯,可是不成功
)
}
複製代碼
分析以下:react
value[ReactiveFlags.SKIP]
:ReactiveFlags.SKIP
的值爲 '__v_skip'
表示有此屬性的值就不能轉換爲響應式數據,你能夠本身手動給你不想轉換的數據添加此屬性,就會使數據必能進行響應式變換(不建議你這麼作,通常自定義組件會有這個屬性)。api
isObservableType(toRawType(value))
: 這個語句相對複雜一些,能夠拆開來看bash
a. toRawType(value)
: 這個方法是獲取傳入值得原始類型,好比 [] ===> Array
這個類型的獲取是經過 Object.toString.call(target)
獲取,而後截取的。 b.isObservableType
就是判斷是不是 object array map set weakmap weakset
其中的一種,若是是就符合要求能夠建立,這樣子的限制也說明了 vue3 但願你是真正的想使某種數據結構變爲響應式時才使用 reactive
類的 api,而不是什麼數據都是進行轉換。數據結構
vue3 提出了 readonly
數據,表示數據只可讀,不了修改;因此,響應式處理的 api 通常是兩個版本:普通版本 和 readonly 版本。注意,這兩種數據時互斥的,也就是不能互相轉換,也不能同時擁有兩種類型。ui
一個是普通的響應式版本,一個是 只讀的版本,根據須要取用。
注意: 這兩個 api 會對數據進行深層次的處理,若是屬性時對象,依然會處理成響應式的數據,這一點區別於下面的兩個 apispa
錢響應的版本,一個是普通的響應式版本,一個是 只讀的版本,根據須要取用。code
上面兩組 api 能夠理解爲第一組是深拷貝,第二組是 淺拷貝server
這裏的判斷 api 就是其表面的語義。這裏只作列舉不會深刻研究,會在下一節研究 vue3 使用 proxy
設置 set
和 get
中詳細分析。對象