1.Vue3 中 ref 和 reactive 都是深度監聽
默認情況下,
無論是通過 ref 還是 reactive 都是深度監聽。
深度監聽存在的問題:
如果數據量比較大,非常消耗性能。
有些時候我們並不需要對數據進行深度監聽。
這個時候就沒有必要使用ref和reactive
2.說明 ref 對數據進行深度監聽
<template>
<div>
<div>
<li>{{state}}</li>
<button @click="func1">按鈕</button>
</div>
</div>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'App',
setup(){
let state=ref({
a:'a',
b:{
b1:"b1",
c:{
c1:"c1",
d1:{
e1:"e1",
f1:{
f1:"f1"
}
}
}
}
})
function func1(){
state.value.b.c.d1.f1.f1="f1f1f1f1"
}
return {state,func1}
},
}
</script>

通過上面的代碼,我們發現無論寫多少層數據;
數據層級有多深,ref始終會對數據進行深度監聽。
這顯然不是我們需要的。
我們迫切需要對數據進行非深度監聽。
這個時候,我們的shallowReactive和shallowRef就出場了。
3.使用 shallowReactive 非深度監聽
前面我們說道:
默認情況下,無論是通過 ref 還是 reactive 都是深度監聽。
所以Vue3為我們提供了,shallowReactive進行非深度監聽。
shallowReactive只會包裝第一層的數據
默認情況它只能夠監聽數據的第一層。
如果想更改多層的數據,
你必須先更改第一層的數據。
然后在去更改其他層的數據。
這樣視圖上的數據才會發生變化。
<template>
<div>
<div>
<div>{{state}}</div>
<button @click="func1">按鈕</button>
</div>
</div>
</template>
<script>
import {shallowReactive} from 'vue'
export default {
name: 'App',
setup(){
let state=shallowReactive({
a:'a',
b:{
b1:"b1",
c:{
c1:"c1",
d1:{
e1:"e1",
f1:{
f1:"f1"
}
}
}
}
})
function func1(){
console.log( state );//只有第一層
console.log( state.b.b1 )
console.log(state.b.c )
console.log( state.b.c.d1 )
console.log( state.b.c.d1.f1 );
// 直接更改其他層的數據,會失敗的哈
// state.b.c.d1.f1.f1="f1f1f1f1"
// 先更改第一層,然后在更改其他層就會成功
state.a="啊啊啊"
state.b.c.d1.f1.f1="f1f1f1f1"
}
return {state,func1}
},
}
</script>

4.使用 shallowRef 進行非深度監聽
注意點:如果是通過shallowRef創建的數據。
那么Vue監聽的是.value 變化。
並不是第一層的數據的變化。
因此如果要更改shallowRef創建的數據。
應該xxx.value={}
<template>
<div>
<div>
<div>{{state}}</div>
<button @click="func1">按鈕</button>
</div>
</div>
</template>
<script>
import {shallowRef} from 'vue'
export default {
name: 'App',
setup(){
let state=shallowRef({
a:'a',
b:{
b1:"b1",
c:{
c1:"c1",
d1:{
e1:"e1",
f1:{
f1:"f1"
}
}
}
}
})
function func1(){
// 通過 state.value的方式直接去更改
state.value={
a:'我是a',
b:{
b1:"我是b1",
c:{
c1:"我是c1",
d1:{
e1:"我是e1",
f1:{
f1:"f1"
}
}
}
}
}
}
return {state,func1}
},
}
</script>

5.triggerRef更改shallowRef創建的數據
triggerRef 可以直接去更改
shallowRef創建數據的某一層。
需要我們注意的是:
vue3中值提供了triggerRef這個方法,
但是並沒有提供triggerReactive的方法。
也就是說triggerRef 【不可以】去更改
shallowReactive創建的數據
<template>
<div>
<div>
<div>{{state}}</div>
<button @click="func1">按鈕</button>
</div>
</div>
</template>
<script>
import {shallowRef,triggerRef} from 'vue'
export default {
name: 'App',
setup(){
let state=shallowRef({
a:'a',
b:{
b1:"b1",
c:{
c1:"c1",
d1:{
e1:"e1",
f1:{
f1:"f1"
}
}
}
}
})
function func1(){
// 直接更改你需要修改某一層的數據
state.value.b.c.d1.f1="我是f1";
triggerRef(state)
}
return {state,func1}
},
}
</script>

通過上面的幾個例子
我們知道一般情況下。我們使用ref和reactive即可。
只有在監聽的數據量比較大的時候。
才使用shallowReactive和shallowRef。