ref和computed的联系

0 阅读2分钟

从底层看 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