ref 和 reactive 怎么选?为什么需要 .value?
先理解原理和示例,再练习完整口述与追问。
回答要点
ref 用包装对象的 value 访问承载值,可用于基本类型和对象;reactive 返回对象代理。脚本中通常通过 .value 访问 ref,模板存在解包规则。ref 包装的对象默认也可深层响应。
原理拆解
ref 用有 value 访问入口的容器表达一个可追踪绑定,既可保存原始值,也可保存对象;对象 ref 默认仍会把可代理的内部对象转为响应式。reactive 返回对象代理,适合字段相对稳定的对象。ref.value 可整体替换而保留 ref 身份,reactive 变量若被重新赋成另一个对象,旧引用与依赖不会凭空转移。
示例与推演
import { ref, reactive } from 'vue'
const count = ref(0)
const user = ref({ name: 'A' })
const form = reactive({ city: '' })
count.value++
user.value = { name: 'B' }
form.city = 'Shanghai'
脚本通过 .value 命中 ref 的访问器,模板在规定的上下文会自动解包;不能把所有位置都理解为自动省略 .value。
易错点
reactive 不能直接用于把一个普通数字变成响应式变量。数组或集合中的 ref、嵌套解包规则有边界,遇到问题先区分“容器”与“容器当前值”。
参考回答可直接练习口述
ref 用一个响应式容器保存值,脚本通常通过 .value 读写,可装基本类型或对象;对象默认会转换成深层响应式。reactive 直接返回对象代理,适合保持稳定引用的一组状态。模板对顶层 ref 等有解包规则,但并非所有嵌套位置都自动解包。我的选择主要看是否需要整体替换值,以及组合函数的返回接口。
面试官可能继续问追问与完整解答展开收起
追问
数组或 Map 中的 ref 一定自动解包吗?替换整个 reactive 变量为什么容易失去原有订阅关系?
追问回答
响应式数组元素和 Map 值中的 ref 通常仍需 .value。把 let state = reactive(...) 再指向另一个代理,不会让所有已订阅旧对象的人自动改订阅新对象;需要整体替换时可用 ref,或保持 reactive 容器并更新其属性。