Vue3中shallowReactive和shallowRef对数据进行非深度监听
2023-09-18 10:50:40
Vue3 中 ref 和 reactive 都是深度监听
在 Vue3 中,ref 和 reactive 都是用来创建响应式数据的,但它们在底层实现上存在着一些差异。
- ref 是通过 Object.defineProperty() 方法来创建的,它会将一个对象或者数组的每个属性都变成响应式的。
- reactive 是通过 Proxy 对象来创建的,它会将整个对象或者数组都变成响应式的。
这意味着,如果我们使用 ref 来创建一个对象或者数组,那么对这个对象或者数组的任何属性进行更改,都会触发组件的重新渲染。
const obj = ref({
name: 'John Doe',
age: 30
});
obj.value.name = 'Jane Doe'; // 触发重新渲染
如果我们使用 reactive 来创建一个对象或者数组,那么对这个对象或者数组的任何属性进行更改,也会触发组件的重新渲染。
const obj = reactive({
name: 'John Doe',
age: 30
});
obj.name = 'Jane Doe'; // 触发重新渲染
说明 ref 对数据进行深度监听
当我们使用 ref 来监听一个对象或者数组时,这个对象或者数组的每个属性都会被标记为脏,从而触发组件的重新渲染。
const obj = ref({
name: 'John Doe',
age: 30,
address: {
street: '123 Main Street',
city: 'Anytown',
state: 'CA',
zip: '12345'
}
});
obj.value.address.street = '456 Elm Street'; // 触发重新渲染
在上面的例子中,当我们更改 obj.value.address.street 的值时,整个 obj 对象都会被标记为脏,从而触发组件的重新渲染。
使用 shallowReactive
为了只对某些属性进行监听,而不希望对整个对象或数组进行监听,可以使用 shallowReactive 来创建一个浅响应式对象或数组。
const obj = shallowReactive({
name: 'John Doe',
age: 30
});
obj.name = 'Jane Doe'; // 触发重新渲染
obj.age = 31; // 不触发重新渲染
在上面的例子中,当我们更改 obj.name 的值时,整个 obj 对象都会被标记为脏,从而触发组件的重新渲染。但是,当我们更改 obj.age 的值时,obj 对象不会被标记为脏,因此不会触发组件的重新渲染。
这是因为 shallowReactive 只会对对象的顶层属性进行监听,而不会对对象的嵌套属性进行监听。
const obj = shallowReactive({
name: 'John Doe',
age: 30,
address: {
street: '123 Main Street',
city: 'Anytown',
state: 'CA',
zip: '12345'
}
});
obj.address.street = '456 Elm Street'; // 不触发重新渲染
在上面的例子中,当我们更改 obj.address.street 的值时,obj 对象不会被标记为脏,因此不会触发组件的重新渲染。这是因为 shallowReactive 只会对对象的顶层属性进行监听,而不会对对象的嵌套属性进行监听。
使用 shallowRef
shallowRef 和 shallowReactive 类似,都是用来创建浅响应式数据,但 shallowRef 是用来创建浅响应式值,而 shallowReactive 是用来创建浅响应式对象或数组。
const name = shallowRef('John Doe');
name.value = 'Jane Doe'; // 触发重新渲染
在上面的例子中,当我们更改 name.value 的值时,name 对象会被标记为脏,从而触发组件的重新渲染。
但是,当我们使用 shallowRef 来创建一个嵌套对象或数组时,嵌套对象或数组的属性不会被标记为脏,因此不会触发组件的重新渲染。
const obj = shallowRef({
name: 'John Doe',
age: 30,
address: {
street: '123 Main Street',
city: 'Anytown',
state: 'CA',
zip: '12345'
}
});
obj.value.address.street = '456 Elm Street'; // 不触发重新渲染
在上面的例子中,当我们更改 obj.value.address.street 的值时,obj 对象不会被标记为脏,因此不会触发组件的重新渲染。这是因为 shallowRef 只会对值的顶层属性进行监听,而不会对值的嵌套属性进行监听。
总结
在 Vue3 中,shallowReactive 和 shallowRef 可以用来创建浅响应式数据。浅响应式数据只对顶层属性进行监听,而不会对嵌套属性进行监听。这可以减少组件的重新渲染次数,提高应用程序的性能。