响应式的哲学

在深入学习 Vue 3 的过程中,不管是新手还是老鸟,都会遇到一个经典问题:refreactive 到底用哪个?

官方的定义

  • ref:接受一个内部值并返回一个响应式且可变的 ref 对象。ref 对象仅有一个 .value property,指向该内部值。
  • reactive:返回对象的响应式副本。

看起来很简单,对吧?ref 处理基本类型,reactive 处理对象。但是在实际开发中,情况远比这复杂。

踩坑实录

我曾经试图用 reactive 去定义一个数组,结果发现直接重新赋值会丢失响应性!

1
2
3
let list = reactive([])
// ... 异步获取数据后
list = newData // ❌ 响应性丢失!界面不更新!

为什么?因为 reactive 返回的是一个 Proxy 对象,直接赋值 list = newData 只是修改了变量 list 的引用,并没有修改原来的 Proxy 对象。

正确做法是用 ref,或者用 list.push(...newData)。但是 ref 每次都要写 .value,真的好烦啊!在模板里倒是会自动解包,但在 JS 逻辑里,少写一个 .value 就能让你调试半天。

深入思考

ref 更像是“指针”,明确地告诉我们这里有一个需要被追踪的值;而 reactive 则更贴近原生对象的直觉。

简单来说,它就像是一个黑盒子,你输入 A,它输出 B,但中间发生了什么,或者是有没有响应到,你只能看输出和输入的情况。

代码示例方面,我尝试写了一个 Demo,结果控制台满屏飘红。这哪里是写代码,简直是在扫雷。每一个变量的定义都充满了不确定性,每一个函数的调用都像是在赌博。

也许,与其纠结用哪个,不如统一用 ref 一把梭?毕竟,显示地使用 .value 虽然繁琐,但至少心安。

思考