监听的意思就是数据双向绑定,视图根据数据变化
递归监听
默认情况下,无论是使用ref和reactive都是递归监听,但是如果数据量非常大的话,就特别消耗性能
不信的话,我举个例子
import {reactive } from "vue";
setup() {
let state = reactive({
a: "a",
gf: {
b: "b",
f: {
c: "c",
s: {
d: "d",
},
},
},
});
console.log(state)
console.log(state.gf)
console.log(state.gf.f)
console.log(state.gf.f.s)
}
对吧,内部每个都做了递归,尤大佬给我们提供了一个方法,避免这样
非递归监听
shallowReactive:第一层数据如果不该变的话,视图不会更新
代码
import { shallowReactive } from "vue"
setup() {
let state = shallowReactive({
a: "a",
gf: {
b: "b",
f: {
c: "c",
s: {
d: "d",
},
},
},
});
state.a = '1';
state.gf.b = '2';
state.gf.f.c = '3';
state.gf.f.s.d = '4'
console.log(state)
console.log(state.gf)
console.log(state.gf.f)
console.log(state.gf.f.s)
}
只有第一层发生了递归监听,当我们第一层数据没改变的时候,下面层的数据改变了是不会更新我们的UI视图的
shallowRef:shallowRef创建的数据,vue监听的是.value的变化,并不是第一层的变化
import { shallowRef} from "vue";
setup() {
let state = shallowRef({
a: "a",
gf: {
b: "b",
f: {
c: "c",
s: {
d: "d",
},
},
},
});
//必须这样修改
state.value = {
a: "1",
gf: {
b: "2",
f: {
c: "3",
s: {
d: "4",
},
},
},
};
}
但是我们就想修改某一层的值怎么办?这样即可
import { triggerRef} from "vue";
state.value.gf.f.s.d = '4';
triggerRef(state)
注意:vue3只提供了triggerRef,所以如果是reactive类型的数据,是无法主动触发页面更新的
再说明下ref和reactive
ref
1.ref也是响应式数据方法,ref可以实现对简单值的监听,字符串,数字等
2.ref底层的本质其实还是reactive,系统会自动根据我们给ref传入的值将
它转换成ref(xx) ->reactive({value:xx})
3.在vue中使用ref的值不用通过value获取,在js中使用ref的值必须通过value获取
reactive
1.reactive是vue3中提供的实现响应式数据的方法
2.vue2响应式数据是通过defineProperty,vue3是通过es6的proxy实现
3.reactive参数必须是对象或者数组
这俩区别
1.如果在template里使用的是ref类型的数据,那么Vue会自动帮我们添加.value
2.如果在template里使用的是reactive类型的数据,那么Vue不会自动帮我们添加.value
3.vue内部根据一个v_isRef属性来判断的,ref的v_isRef属性为true,reactive就没有这个属性