通俗易懂:Vue3的ref()运行机理
把 ref()
想象成一只 “魔法盒子” ——
你往里面放任何普通的东西(数字、字符串、布尔值、对象、数组……),
盒子立刻把它变成 “带警报器的数据”:
谁要是敢改里面的值,警报器立刻响起,Vue 就知道“数据变了,得去更新界面”。
一、为什么要用魔法盒子?
在 Vue3 里,普通的 JavaScript 变量(例如 let count = 0
)没有魔法。
count++
以后,Vue 根本不知道“数据变了”,界面不会跟着刷新。
于是 Vue 提供了 ref()
这只盒子,让“变量变魔法”。
二、盒子的 3 个关键点(拆开看)
-
装进去
import { ref } from 'vue' const count = ref(0) // 把 0 放进盒子
-
读出来
盒子外层是“壳”,真正数据在.value
里:console.log(count.value) // 0
-
改数据
只要改.value
,警报器就响:count.value = 5 // 触发 Vue 的“更新巡逻队”去刷新界面
三、盒子内部到底做了什么?(通俗版)
-
壳(RefImpl 对象)
你拿到的count
其实是一个对象:{_value: 0, // 真正存数据的地方dep: Set(), // “订阅列表”——谁在用我?get value() { ... },set value(newVal) {// 1. 保存新值// 2. 拉响警报——通知所有订阅者:数据变了!} }
-
Proxy 的魔法
如果你放的是对象或数组,Vue 会再套一层 Proxy(响应式深层代理)。
这样即使改对象里的属性,也能触发更新。const user = ref({ name: 'Tom' }) user.value.name = 'Jerry' // 也能触发界面更新
四、在模板里的“语法糖”
在 <template>
里,Vue 帮你省掉 .value
:
<template><p>{{ count }}</p> <!-- 实际读取 count.value --><button @click="count++">+</button> <!-- 实际执行 count.value++ -->
</template>
注意:在 JavaScript 代码 里必须写 .value
,模板里可以偷懒。
五、常见误区提醒
错误示例 | 正确写法 |
---|---|
let count = ref(0); count = 1 | count.value = 1 |
ref(obj).name = 'xxx' | const objRef = ref(obj); objRef.value.name = 'xxx' |
六、一句话总结
ref()
就是 Vue3 的“魔法盒子”:
- 包装原始值 → 让它响应式
- 读取要 .value → 在代码里
- 模板里省 .value → 语法糖
- 内部用 Proxy + Dep 列表 → 数据一变,界面立刻刷新。