Vue 3 模板中可直接使用 setup 返回的 ref 变量(如 count),无需 .value,前提是 ref 必须作为 return 对象的顶层属性;若返回 count.value、嵌套对象或解构后未用 toRefs,则无法自动解包。

在 Vue 3 的 setup 中,使用 ref 创建的响应式变量,**模板中可以直接使用,无需写 .value** —— 这是 Vue 模板编译器自动做的“解包”(unwrapping),前提是该 ref 变量被**直接作为顶层属性返回**(即出现在 return 对象中)。
✅ 正确返回方式:直接 return ref 变量
只要你在 setup 中用 ref() 创建变量,并把它作为对象的属性名原样返回,Vue 就会在模板中自动读取其 .value:
import { ref } from 'vue'
<p>export default {
setup() {
const count = ref(0)
const message = ref('Hello')</p><pre class="brush:php;toolbar:false;">// ✅ 正确:直接以变量名返回
return {
count,
message
}} }
对应模板中可直接写:
<template><div>{{ count }}</div> <!-- 自动读 count.value -->
<button>+1</button>
<p>{{ message }}</p> <!-- 自动读 message.value -->
</template>❌ 常见错误:返回解构后的值或嵌套对象
以下写法会导致模板中失去响应性或无法自动解包:
-
返回
count.value(原始值):丢失响应性,模板变成静态值 -
返回包装对象如
{ count: count.value }:只是普通 JS 对象,不是 ref,不响应 -
返回嵌套结构如
{ state: { count } }:模板需写{{ state.count }},但此时state.count是 ref,不会自动解包 → 显示为[object Object]
? 补充说明:哪些情况会“不自动解包”?
模板中自动解包只发生在:变量是从 setup 返回对象的顶层属性,且该属性值本身是 ref。其他情况需手动 .value:
- 在
computed、watch等函数内部访问 ref → 必须用.value - 在
setup的 JS 逻辑中 → 全部用.value - 通过解构获取(如
const { count } = toRefs(props))→ 解构后仍是 ref,模板中仍可直接用,因为toRefs保持了 ref 引用
? 进阶技巧:统一管理多个 ref(推荐用 reactive + toRefs)
如果 ref 变量较多,也可用 reactive 包裹对象,再用 toRefs 解构返回,效果等价:
import { reactive, toRefs } from 'vue'
<p>export default {
setup() {
const state = reactive({
count: 0,
message: 'Hello',
loading: false
})</p><pre class="brush:php;toolbar:false;">// ✅ toRefs 会把每个属性转为 ref,支持模板自动解包
return {
...toRefs(state)
}} }
模板中依然写 {{ count }}、{{ message }},简洁且响应式有效。











