浅层响应式对象
前端精髓
共 1349字,需浏览 3分钟
·
2022-05-13 10:07
深层响应性
在 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) // 0
state.count = 1
console.log(count.value) // 1
shallowReactive 和 reactive 不同,属性的值会被原样存储和暴露。
const count = ref(0)
const state = shallowReactive({
count
})
console.log(state.count) // { value: 0 }
state.count = 1
console.log(count.value) // 1
浅层数据结构应该只用于组件中的根级状态。请避免将其嵌套在深层次的响应式对象中,因为它会创建一个具有不一致的响应行为的树,这可能很难理解和调试。
评论