vue3 响应式 API:shallowRef()和shallowReactive()
shallowRef()
shallowRef()
是一个用于创建浅层响应式引用的函数。它创建一个响应式数据,但只对顶层属性进行响应式处理。
特点: 只跟踪引用值的变化,不关心值内部的属性变化。
<template>
<div>{{ shallowRefObj }}</div>
<button @click="changeShallowRefObj">直接修改shallowRefObj</button>
<button @click="changeMessage">修改message属性</button>
</template>
<script setup lang="ts">
import { shallowRef } from 'vue';
const shallowRefObj = shallowRef({
message: 'Hello'
})
const changeShallowRefObj = () => {
// 以下操作会触发响应式更新,因为直接修改了引用本身
shallowRefObj.value = { message: 'hello World!' }
}
const changeMessage = () => {
// 以下操作不会触发响应式更新,因为只是修改了引用对象的属性
shallowRefObj.value.message = 'New message'
console.log('执行changeMessage()后:', shallowRefObj)
}
</script>
- 执行
changeShallowRefObj
方法,修改shallowRefObj
,触发响应式更新:
- 执行
changeMessage
方法,修改shallowRefObj
的message
属性,不会触发响应式更新。
- 执行方法后,devtools查看setup里的数据、页面渲染结果如上图所示,
shallowRefObj
的message
属性值没有任何改变。 - 查看
console.log('执行changeMessage()后:', shallowRefObj)
在控制台的打印结果:shallowRefObj
的message
属性值已经被修改。
与ref()
的区别
ref()
创建的是深度响应式引用,对引用对象的属性的修改也会触发响应式更新。shallowRef()
创建的浅层 ref 的内部值将会原样存储和暴露,并且不会被深层递归地转为响应式。只有对.value
的访问是响应式的。
应用场景
shallowRef()
常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。
shallowReactive()
shallowReactive()
是一个用于创建浅层响应式对象的函数。
shallowReactive()
创建的响应式对象是浅层的:
- 只有对象的直接属性是响应式的,对象内部的嵌套属性不是响应式的。
<template>
<div>{{ shallowReactiveObj }}</div>
<button @click="changeMessage">修改message属性</button>
<button @click="changeProperty">修改property属性</button>
</template>
<script setup lang="ts">
import { shallowReactive } from 'vue';
const shallowReactiveObj = shallowReactive({
message: 'Hello',
nestedObject: {
property: 'value'
}
});
const changeMessage = () => {
// 以下操作会触发响应式更新,因为直接修改了浅层响应式对象的属性
shallowReactiveObj.message = 'hello World!'
};
const changeProperty = () => {
// 以下操作不会触发响应式更新,因为是修改嵌套对象的属性
shallowReactiveObj.nestedObject.property = 'New Value';
console.log('执行changeProperty()后:', shallowReactiveObj);
};
</script>
- 执行
changeMessage
方法,修改浅层响应式对象shallowReactiveObj
的message
属性,触发响应式更新:
- 执行
changeProperty
方法,修改浅层响应式对象shallowReactiveObj
的嵌套属性property
,不会触发响应式更新:
- 执行方法后,devtools查看setup里的数据、页面渲染结果如上图,
shallowReactiveObj
的嵌套属性property
没有任何改变。 - 查看
console.log('执行changeProperty()后:', shallowReactiveObj);
在控制台的打印结果:shallowReactiveObj
的嵌套属性property
已经被修改。
与reactive()
的区别
reactive()
创建的是深度响应式对象,对象的所有属性(包括嵌套对象的属性)都是响应式的。shallowReactive()
创建的浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为ref
的属性不会被自动解包了。