Vue 3与@vue/composition-api嵌套ref/computed取值行为差异是否正常
跨Vue环境下嵌套Ref/Computed的取值行为差异
基础测试样本
const options = ref([{ val: computed(() => 10) }])
不同环境的取值表现
Vue 2 + @vue/composition-api 环境
嵌套在普通对象中的Ref/Computed实例不会被自动解包,必须手动通过.value属性才能获取对应的计算结果:
console.log(options.value[0].val.value) // 输出10
原生 Vue 3 环境
Ref/Computed 被嵌套在响应式容器(包括ref包裹的数组、对象结构)中时,会被自动深层解包,无需手动追加.value即可直接拿到值:
console.log(options.value[0].val) // 输出10
业务场景下的实际影响
在封装自定义Select、Option组件的场景中,组件会维护全局已注册的Option列表,列表的类型定义如下:
type Option = { value: string; label: string; root: Ref<HTMLElement> }; const options: Ref<Array<Option>> = ref([]);
遍历列表读取Option根DOM引用的逻辑在两个环境下存在明显差异:
- Vue 3 环境可直接访问值,无需额外操作
options.value.forEach((opt) => console.log(opt.root)) - Vue 2 + @vue/composition-api 环境必须手动访问嵌套Ref的
.value属性才能拿到值options.value.forEach((opt) => console.log(opt.root.value))
上述行为差异属于框架的设计演进结果,并非功能缺陷:
- Vue 3 重构响应式系统时,专门新增了响应式容器内的嵌套Ref自动解包规则,减少开发过程中手动追加
.value的重复编码量,优化开发体验- @vue/composition-api 作为适配Vue 2的兼容方案,为了不破坏Vue 2原生响应式的运行边界,没有完全复刻Vue 3的深层自动解包逻辑,避免对存量项目逻辑造成非预期影响
如果需要跨两个环境实现统一的取值逻辑,可在注册Option时就对嵌套的Ref做手动解包,或是封装通用的取值工具函数自动判断Ref类型并读取对应值,规避环境差异带来的运行错误。
内容的提问来源于stack exchange,提问作者Shen
相关产品推荐
相关产品推荐

