reactive 簡記
1. 需要注意的是,只有 typeof val=== ‘object’ 的數據才能使用這個api 轉換為響應式數據(如果你違反了這個規則,開發模式下回給你友好親切的提示)
2. 如果你傳入的對象本來是 readonly() 的只讀數據,但是你將其傳入 reactive 時,會直接將這個數據返回。因為轉換不了。
3. 如果你傳入的數據 reactive 的響應式數據,則會直接返回。
他的判斷如下:
這里主需要記住一點,isReadonly 和 target[ReactiveFlges.IS_REACTIVE] 一般情況下是互斥的,也就是只要你的數據時經過 readonly 或者 reactive 轉換的,一定會給你返回你傳入的原值。所以你明白了嗎,readonly 和 reactive 是互斥的數據結構,不能同時使一個數據具有兩種響應式結構,這里說明人家考慮的很全面,完美。
if(target[ReactiveFlges.RAW] && !(isReadonly && target[ReactiveFlges.IS_REACTIVE])) {
return target
}
4. 當你傳遞了一個響應式數據 reactive,如果本身是 reactive 的數據結構,但是你想得到一個 readonly 的結構,對不起,不會給你。
如果一個對象的 ReactiveFlags.RAW === “__v_raw”存在,就說明已經進行過了響應式處理,接下來的處理是 !(isReadonly && target[ReactiveFlags.IS_REACTIVE]) 前面說過當這個數據時響應式數據時,這倆條件是互斥的,所以這里就直接返回了傳入數據,不會再做一層包裝。
5. 你的數據不止要是 typeof === ‘object’,你還必須的是以下的幾種數據結構,不然任性不給你轉
Object, Array, Map, Set, WeakMap, WeakSet 3.0 給出的數據結構轉換的白名單,這點需要注意,不然得不到響應數據。
這個白名單的另外兩個判斷條件是 對象不能被 makRaw 處理過,判斷是否具有ReactiveFlags.SKIP === "__v_skip"屬性
還有不能經過 Object.frozen() 處理
6. 如果你成功地通過了前面這幾道檢測,那么恭喜你,你可以如願以償的獲得你期望中的新的響應式數據
7。 需要遵守上述規則的 api 有
reactive
shallowReactive
readonly
shallowReadonly
上面的四個 api 他們在內部出了 proxy 的 handler 不同,都是調用 createReactiveObject 進行數據轉換的
8。檢測方法
對應的檢測方法有
isReactive 方法
isReadonly 方法
isProxy 方法
9. 將數據轉換回去
makRaw 顯示的標記某個對象永遠不會成為響應式對象,主要是為對象增加了 ReactiveFlags.SKIP === "__v_skip"屬性
toRaw 方法將會獲得你傳入的原始數據,它主要是通過 ReactiveFlags.RAW === "__v_raw" 屬性,這個屬性在 proxy 的 handler 的get 函數中會直接返回傳入的原始對象,但是其實會多一個 __v_reactive 屬性(也有可能是__v_readonly),記錄響應式對象
__v_reactive 和 _v_readonly 這兩個屬性只能有一個存在在源對象上,他們是在 proxy 處理完對象后,使用
key 就是 __v_reactive 和 _v_readonly 其中之一,主要看你的響應式數據時從哪個響應式 api 中獲得的
Object.defineProperty(obj, key, { // vue3.0 並沒有忘記他
configurable: true,
enumerable: false, //不可枚舉
value // proxy 后的響應式對象
})
