vue 3 模板中 ref 会自动解包,无需写 .value;但在 setup、computed、watch 等 js 逻辑中必须显式使用 .value,嵌套访问、解构 ref、动态 key 等场景仍保持自动解包规则。

Vue 3 的 ref 在模板中会自动解包(unwrapped),所以你不需要写 .value —— 这是 Vue 编译器在模板编译阶段做的语法糖,仅限于模板上下文。
模板中 ref 自动解包的规则
当一个 ref 对象出现在模板插值({{ }})、指令(如 v-if、v-bind)或事件处理器中时,Vue 会自动读取其 .value:
-
{{ count }}→ 等价于{{ count.value }} -
v-if="show"→ 等价于v-if="show.value" -
:disabled="isDisabled"→ 等价于:disabled="isDisabled.value"
但注意:这个解包只发生在模板中。在 setup() 函数、computed、watch 或普通 JS 逻辑里,必须显式使用 .value。
哪些情况不会自动解包?
以下场景 不会 触发自动解包,写了 .value 反而可能出错:
- 嵌套访问:比如
{{ user.name }}中,如果user是ref({ name: 'Alice' }),那user.name是合法的(因为user被解包后是普通对象),但user.value.name就多余且错误 - 解构后的 ref:用
const { count } = toRefs(props)得到的是 ref,解构后仍需在模板中直接写{{ count }},不能写{{ count.value }} - 数组索引或动态 key:如
{{ list[0] }}或{{ obj[key] }},只要list或obj是 ref,依然会解包
如何避免 .value 写多?实用技巧
核心原则:模板里一律不写 .value;逻辑里该写就写。几个小提醒:
- 用
toRef或toRefs把响应式对象的属性转成 ref,方便在模板中直接用,比如const { title, id } = toRefs(state),然后模板中写{{ title }} - 不要在模板里对 ref 做赋值(如
{{ count = 5 }}),这不合法,也触不解包逻辑 - 函数返回 ref?比如
{{ getName() }},只要getName()返回的是 ref,也会被解包 —— 但更推荐返回普通值,语义更清晰
记住:自动解包是 Vue 模板的“透明优化”,不是运行时魔法。它让模板更简洁,但背后逻辑始终一致 —— ref 的本质还是个带 .value 的对象。









