在 Vue 3 的 Composition API 里,reactive()
和 ref()
都是用來把「普通數據」變成「響應式數據」的函數。
一句話區別:
reactive()
只能包裹對象/數組;ref()
可以包裹任何類型,但在 模板 里讀取時,不需要.value
。
下面按「概念 → API → 使用 → 常見注意點」展開。
1. 為什么需要它們
Vue 2 里只有 data() { return {...} }
這一種聲明響應式數據的方式。
Vue 3 的 Composition API 把「聲明響應式」拆成了兩個底層函數:
函數 | 適合場景 | 返回值 |
---|---|---|
reactive() | 對象、數組 | Proxy |
ref() | 基本類型、對象、數組 | RefImpl 對象 |
2. reactive() 用法
import { reactive } from 'vue'const state = reactive({count: 0,list: [1, 2, 3]
})// 使用
state.count++ // ? 觸發視圖更新
state.list.push(4) // ? 觸發視圖更新
- 模板里直接寫:
<template><p>{{ state.count }}</p><button @click="state.count++">+</button>
</template>
?? 注意
- 不能對
state
重新賦值(會失去響應式)
state = { count: 10 } // ? 錯誤
- 解構會丟失響應式
const { count } = state // ? count 不是響應式
// 正確:用 toRefs(state) 解構
3. ref() 用法
import { ref } from 'vue'const count = ref(0)
const name = ref('Vue')
const obj = ref({ a: 1 }) // 也可以包對象
- 腳本里取值 / 賦值 必須加
.value
count.value++ // ?
obj.value.a = 2 // ?
- 模板里會自動解包,不寫
.value
<template><p>{{ count }}</p> <!-- 模板里直接寫 count --><button @click="count++">+</button>
</template>
?? 注意
- 重新賦值不會破壞響應式
count.value = 100 // ? 仍是響應式
- 對對象/數組用
ref()
時,深層屬性依舊是響應式,因為內部會遞歸reactive()
。
4. 什么時候用哪個?
場景 | 推薦 |
---|---|
需要一組關聯屬性(表單、狀態對象) | reactive() |
只有一個基本類型(數字、布爾、字符串) | ref() |
需要解構或重新賦值(替換整個對象) | ref() |
需要深層響應式且結構固定 | reactive() |
5. 組合使用示例
<script setup>
import { reactive, ref } from 'vue'// 一整個對象
const user = reactive({name: 'Tom',age: 18
})// 單個值
const loading = ref(false)// 方法
function addAge() {user.age++loading.value = true
}
</script><template><div v-if="!loading">{{ user.name }} - {{ user.age }}歲<button @click="addAge">長大一歲</button></div><p v-else>加載中...</p>
</template>
6. 速記口訣
- 對象用
reactive
,基本類型用ref
。 - 模板里
ref
省.value
,腳本里千萬別省。 - 解構對象用
toRefs()
,重新賦值用ref()
。