浅层响应式对象

深层响应性
在 Vue 中,data 状态都是默认深层响应式的。这意味着即使在更改深层次的对象或数组,你的改动也能被检测到。
export default {data() {return {obj: {nested: { count: 0 },arr: ['foo', 'bar']}}},methods: {mutateDeeply() {// 以下都会按照期望工作this.obj.nested.count++this.obj.arr.push('baz')}}}
在组合式 API 中 reactive() 返回一个对象的响应式代理。
const obj = reactive({ count: 0 })obj.count++
响应式转换是“深层”的:它会影响到所有嵌套的 property。一个响应式对象也将深层地解包任何 ref property,同时保持响应性。
浅层响应式
你也可以直接创建一个浅层响应式对象。它们仅在顶层具有响应性,一般仅在某些特殊场景中需要。
若要避免深层响应式转换,只想保留对这个对象顶层次访问的响应性,请使用 shallowReactive() 作替代。
shallowReactive() 是 reactive() 的浅层作用形式。
const state = shallowReactive({foo: 1,nested: {bar: 2}})// 更改状态自身的属性是响应式的state.foo++// ...但下层嵌套对象不会被转为响应式isReactive(state.nested) // false// 不是响应式的state.nested.bar++
和 reactive()不同,这里不会有深层次转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着属性为 ref 的值不会被自动解包了。
ref 在响应式对象中的解包
当一个 ref 作为一个响应式对象的 property 被访问或更改时,它会自动解包,因此会表现得和一般的 property 一样:
const count = ref(0)const state = reactive({count})console.log(state.count) // 0state.count = 1console.log(count.value) // 1
shallowReactive 和 reactive 不同,属性的值会被原样存储和暴露。
const count = ref(0)const state = shallowReactive({count})console.log(state.count) // { value: 0 }state.count = 1console.log(count.value) // 1
浅层数据结构应该只用于组件中的根级状态。请避免将其嵌套在深层次的响应式对象中,因为它会创建一个具有不一致的响应行为的树,这可能很难理解和调试。
评论
