我们用**“追踪器”“盒子”**的例子重来一遍。

Vue 的核心任务就是:你要是改了数据,Vue 得立马知道(以便更新网页)。


1. 为什么 ref 需要 .value

想象你要追踪一个数字 0
在 JS 的世界里,数字就像一枚硬币

  • 你没法在硬币上装“GPS追踪器”。硬币太小了,也是死物,没地方贴。

Vue 怎么做?
Vue 给你发了一个盒子(这就是 ref)。
它把硬币(0)放进了盒子里,然后在盒子上装了警报器。

  • 当你拿变量时: 你拿到的不是硬币,而是整个盒子
  • 当你要改值时: 你必须打开盒子,这就叫 .value
    • count 是盒子。
    • count.value 是“打开盒子拿硬币”这个动作。

结论: 因为硬币(数字、字符串)本身装不了监控,只能装在盒子上。所以你每次必须**“打开盒子”(.value)** 才能摸到数据。


2. 为什么 reactive 不需要 .value

想象你要追踪一个背包(里面有很多东西)。
在 JS 的世界里,对象(Object)就像这个背包

  • 背包很大,Vue 有能力直接把“GPS追踪器”缝在背包的拉链上。

Vue 怎么做?
Vue 给了你一个被改装过的背包(这就是 reactive)。

  • 当你拿变量时: 你直接拿到了这个带监控的背包。
  • 当你要改值时: 你直接拉开拉链拿东西就行了(比如 backpack.name)。
  • 不需要 .value: 因为监控就在背包皮上,你只要动背包,Vue 就知道。不需要再往外面套个盒子了。

3. 为什么 reactive 容易出问题(解构丢失响应性)?

这是最关键的。

如果你用 reactive 创建了一个智能背包 state,里面放了一个苹果 count

const state = reactive({ count: 0 }); // state 是智能背包

如果你写了这行代码:

let { count } = state; // 从背包里把苹果拿出来,揣自己兜里

这时候发生了什么?
你把苹果(count)从智能背包里掏出来了,放在了普通的桌子上。

  • 智能背包(state)有监控。
  • 但是这个苹果(count)只是一个普通的苹果,它身上没有监控!

所以,当你修改桌子上的这个苹果时,Vue 完全不知道,网页也不会变。这就是所谓的“失去响应性”。

ref(盒子)就不怕这个问题,因为你不管把盒子拎到哪里,盒子上的警报器始终都在。


终极简化总结

  1. Ref (盒子):

    • 针对: 简单的值(数字、字符串)。
    • 样子: const a = ref(0)
    • 操作: 必须用 a.value(打开盒子)才能改。
    • 优点: 盒子随便拎,走到哪都有监控,最稳。
  2. Reactive (智能背包):

    • 针对: 复杂的对象(一堆数据)。
    • 样子: const b = reactive({ x: 1 })
    • 操作: 直接 b.x(拉拉链)就能改,不需要 .value
    • 缺点: 里面的东西不能掏出来单独用,掏出来就没监控了。

场景,推荐使用,理由
“基础类型 (boolean, string, number)”,ref,const showModal = ref(false) 必须用 ref,reactive 做不到。
表单数据对象 (Form Model),reactive,“const form = reactive({ name: ‘’, age: 0 }) 因为表单字段很多,直接 form.name 很方便,且表单通常作为一个整体传递。”
后端返回的列表数据,ref,const list = ref([]) 虽然是数组,但如果后端返回新数组直接替换整个 list,用 reactive 会比较麻烦(不能直接赋值替换,会导致引用丢失),用 ref 直接 list.value = newData 最安全。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐