深層次響應式 reactive 和 ref 創建的對象都是深層次的,對象的根屬性和嵌套屬性都是響應式的。 深層次轉換是遞歸地轉為響應式,對象里的每個屬性訪問都將觸發代理的依賴追蹤,這種性能負擔通常這隻有在處理超大型數組或層級很深的對象時才比較明顯。例如,一次渲染需要訪問 100000+ 個屬性時,才 ...
深層次響應式
reactive
和 ref
創建的對象都是深層次的,對象的根屬性和嵌套屬性都是響應式的。
深層次轉換是遞歸地轉為響應式,對象里的每個屬性訪問都將觸發代理的依賴追蹤,這種性能負擔通常這隻有在處理超大型數組或層級很深的對象時才比較明顯。例如,一次渲染需要訪問 100000+ 個屬性時,才會變得比較明顯。因此,shallowRef
或 shalloReactive
只在少數特定的場景才會使用。
const state = reactive({
foo: {
bar: 1
},
foobar: 2
});
淺層次響應式
shallowReactive
shallowReactive
創建的響應式對象只在其根屬性是響應式的,對所有深層的對象不會做任何的遞歸深層轉換處理,否則和 reactive 沒區別。
淺層響應式對深層級屬性的訪問會很快,但代價是,所有深層的對象視為非響應式的。
const state = shallowReactive({
foo: {
bar: 1
},
foobar: 2
});
上圖中,state.foo.bar
沒有發生改變,只有在其他響應式更新之後,才間接地更新它的狀態。
替換頂級對象失去響應式
對於 reactive
和 shallowReactive
,如果替換了頂級對象就會失去響應式:
let state = shallowReactive({
foo: {
bar: 1
},
foobar: 2
});
function changeState() {
state = {
foo: {
bar: 1000
},
foobar: 2000
};
}
如上圖所示,state.foobar
在替換頂級對象之前,一直是有響應式的,但是被替換了之後,就失去了響應式。
需要思考的是,為什麼替換了頂級對就失去了響應式,請先閱讀 Vue 中的響應性是如何工作的,官方文檔給了一個 reactive 和 ref 創建響應式的偽代碼,不難看出,reactive 返回了一個 Proxy。在 getter/setter
上加上 Vue 的追蹤代碼,實現響應式。
一旦這個 Proxy 對象被替換了,就沒有了 getter/setter
,即失去了響應式。
shallowRef
與 shallowReactive
不同的是,shallowRef
創建的響應式對象都是淺層的,並不是說它不是響應式,因為有 triggerRef
API 存在,即主動地通知更新。
let state = shallowRef({
foo: {
bar: 1
},
foobar: 2
});
function changeState() {
state.value = {
foo: {
bar: 1000
},
foobar: 2000
};
}
在替換頂層對象之前,點擊按鈕,state.foo.bar
和 state.foobar
都沒有更新。強制通知淺層 ref 更新,可以使用 triggerRef
,具體查看官方文檔:triggerRef。
替換頂級對象不會失去響應式
shallowRef
和 ref
創建的響應式對象被替換了之後,依舊保留響應式。
let state = shallowRef({
foo: {
bar: 1
},
foobar: 2
});
function changeState() {
// 自加不會觸發頁面更新
state.value.foo.bar++;
state.value.foobar++;
// 替換 state.value 的頂級對象頁面才會更新
const replace = {
foo: {
bar: state.value.foo.bar
},
foobar: state.value.foobar
};
state.value = replace;
}
最好的做法是通過 triggerRef
,改造一下代碼:
function triggerUpdate() {
state.value.foo.bar++;
state.value.foobar++;
triggerRef(state);
}
總結 shallowRef
shallowReactive
沒有強制更新的 API,只有第一層屬性是響應式的,且嵌套對象屬性是間接觸發更新的機制。
所以,想要一個淺層的響應式對象,建議使用 shallowRef
,它有 triggerRef
這樣的 API,使用起來靈活。
什麼時候用到淺層響應式
- 在處理大量數據,需要提高性能(優化性能)時;
- 不希望立馬更新,需要自定義更新時機時。