从底层看 computed()的变量是“本质为 Ref”,因为在 Vue 3 的底层实现中,计算属性(computed)返回的对象和 ref() 创建的对象长得一模一样。
虽然它的名字叫 computed,但在 JavaScript 代码里使用时,你需要把它当成 ref 来对待。
这里有三个关键点帮你理解:
它们都是“盒子”(Ref 对象)
在 Vue 3 中,无论是你用 ref(1) 创建的变量,还是用 computed(() => 1) 创建的变量,它们返回的都不是直接的数字 1,而是一个包含值的对象(通常被称为 RefImpl)。
ref:创建一个可以修改的盒子。computed:创建一个只读的盒子(除非你写了 set),里面的值是由其他数据算出来的。
必须用 .value 来访问
正因为它们本质都是这个“盒子”对象,所以在 <script> 标签的 JS 逻辑中,你不能直接拿它去运算,必须先打开盒子。
- 错误写法:
item.type === eggType- 这里
eggType(计算属性命名) 是一个对象[Object],你永远无法让它等于字符串"chocolate"。
- 这里
- 正确写法:
item.type === eggType.value- 这里
.value就是打开盒子,取出里面的真实字符串。
- 这里
这就是为什么说它“本质是 Ref”——因为它们操作方式完全一样,都要点 .value。
底层的关系
从 Vue 源码的角度看(参考之前的搜索结果),ComputedRefImpl(计算属性的类)继承或实现了与 Ref 相同的接口。
- 它们都有
.value属性。 - 它们都能被 Vue 的响应式系统追踪。
- 区别仅在于:
ref的值是你给什么它就是什么;computed的值是它自己算出来的,且默认是只读的。
总结
所以说computed计算命名的变量“本质是 Ref”时,其实是在提醒你一个避坑指南:
只要看到
const xxx = computed(...),你在写代码时就要立刻反应过来:后面用到xxx的时候,千万别忘了加.value!