使用 shallowRef() 来绕开深度响应

Vue的深度响应性在处理大数据时可能导致性能问题。为了解决这个问题,Vue提供了shallowRef和shallowReactive,它们只对数据顶层进行响应式处理,减少不必要的依赖追踪,提高性能。使用这些工具时,深层属性不再响应式,需要通过替换整个对象来触发更新。这种优化适用于大型数据结构和与外部状态管理系统的集成。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

caef0cbbd23e2927584e8b681caac79b.png

Vue 的响应性系统默认是深度的。虽然这让状态管理变得更直观,但在数据量巨大时,深度响应性也会导致不小的性能负担,因为每个属性访问都将触发代理的依赖追踪。好在这种性能负担通常这只有在处理超大型数组或层级很深的对象时,例如一次渲染需要访问 100,000+ 个属性时,才会变得比较明显。因此,它只会影响少数特定的场景。

Vue 确实也为此提供了一种解决方案,通过使用 shallowRef() 和 shallowReactive() 来绕开深度响应。浅层式 API 创建的状态只在其顶层是响应式的,对所有深层的对象不会做任何处理。这使得对深层级属性的访问变得更快,但代价是,我们现在必须将所有深层级对象视为不可变的,并且只能通过替换整个根状态来触发更新:

const shallowArray = shallowRef([
  /* 巨大的列表,里面包含深层的对象 */
])


// 这不会触发更新...
shallowArray.value.push(newObject)
// 这才会触发更新
shallowArray.value = [...shallowArray.value, newObject]


// 这不会触发更新...
shallowArray.value[0].foo = 1
// 这才会触发更新
shallowArray.value = [
  {
    ...shallowArray.value[0],
    foo: 1
  },
  ...shallowArray.value.slice(1)
]

shallowRef shallowRef

shallowRef 和 ref() 不同,浅层 ref 的内部值将会原样存储和暴露,并且不会被深层递归地转为响应式。只有对 .value 的访问是响应式的。

shallowRef() 常常用于对大型数据结构的性能优化或是与外部的状态管理系统集成。

示例

const state = shallowRef({ count: 1 })


// 不会触发更改
state.value.count = 2


// 会触发更改
state.value = { count: 2 }

shallowRef 和 reactive() 不同,这里没有深层级的转换:一个浅层响应式对象里只有根级别的属性是响应式的。属性的值会被原样存储和暴露,这也意味着值为 ref 的属性不会被自动解包了。

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

const state = shallowReactive({
  foo: 1,
  nested: {
    bar: 2
  }
})


// 更改状态自身的属性是响应式的
state.foo++


// ...但下层嵌套对象不会被转为响应式
isReactive(state.nested) // false


// 不是响应式的
state.nested.bar++

通过使用 shallowRef() 和 shallowReactive() 来绕开深度响应,改善页面加载和更新性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值