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。