浅层响应式对象

前端精髓

共 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 = 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


浅层数据结构应该只用于组件中的根级状态。请避免将其嵌套在深层次的响应式对象中,因为它会创建一个具有不一致的响应行为的树,这可能很难理解和调试。


浏览 27
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报