You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中shallowReadonly与配合响应式对象使用的computed有什么区别?

1. 核心定位与响应式逻辑差异

shallowReadonly 是对原响应式对象的浅只读代理包装,本身没有独立的响应式依赖收集逻辑,完全透传原响应式对象的变更:原对象第一层属性禁止修改,深层属性保留完整响应式能力,修改深层属性会直接变更原状态,所有依赖该状态的地方都会同步更新。
computed 是带缓存的计算属性容器,依赖其getter函数内显式访问的响应式变量:只有当依赖变量变更时才会重新执行getter,多次访问未变更的computed值会直接读取缓存,不会重复执行getter逻辑。如果你的getter没有直接返回原响应式对象引用(比如做了数组展开、对象解构、过滤转换等操作),外部修改computed返回值的深层属性完全不会影响原状态。

2. 第一层修改的类型与运行时校验差异

你的测试用例中忽略了一个明显差异:

  • shallowReadonly 包裹的ref,其value本身是第一层只读的,TS会直接禁止对usingShallowReadonly.value[0] = null、usingShallowReadonly.value.push(xxx)这类修改数组/对象第一层属性的操作,运行时也会静默失败。
  • 直接返回原引用的computed,其value的类型和原响应式对象完全一致,TS不会禁止第一层属性修改,运行时也会直接生效修改原状态。

3. 适用场景差异

如果你仅需要对外暴露只读的原状态引用,没有额外的转换、过滤逻辑,优先用shallowReadonly,没有额外的计算属性实例开销,还能从类型和运行时层面禁止第一层的意外修改。
如果需要对原状态做转换、过滤,或者希望对外暴露的是和原状态隔离的拷贝,优先用computed,可以利用缓存减少重复计算开销,也可以通过返回新对象/数组避免外部修改原状态。

场景补充建议

如果你完全不希望外部修改composable内部状态,以上三个方案都有缺陷:computed和shallowReadonly都允许修改深层属性,readonly虽然深层只读,但如果原状态内部有复杂对象,还是可能存在逃逸漏洞。更稳妥的方案是:对外只暴露只读状态+修改状态的方法,内部状态完全不对外暴露。

内容的提问来源于stack exchange,提问作者microHoffman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 20:57:02