Skip to main content

ref() 與 reactive()

在 Vue3 Composition API 中,最常用的就是 響應式資料
Vue 提供了兩個主要 API:ref()reactive(),用來建立可追蹤變化的資料。

1. ref()

  • 適合用來處理「單一值」:字串、數字、布林、甚至物件。
  • 存取或修改時,要透過 .value

範例:計數器

<script setup>
import { ref } from "vue";

const count = ref(0); //將count的預設值設為0

const add = () => {
count.value++;
};
</script>

<template>
<button @click="add">Count: {{ count }}</button>
</template>

📌 重點

  • ref(0) 建立了一個響應式變數。
  • 修改時使用 count.value++
  • 在模板 (template) 中會自動幫你取 .value,所以可以直接寫 {{ count }}

使不使用 ref 的差異

我們將原本範例中 count 的 ref 拿掉,程式碼如下

<script setup>
import { ref } from "vue";

const count = 0; //將count的預設值設為0

const add = () => {
count.value++;
};
</script>

<template>
<button @click="add">Count: {{ count }}</button>
</template>

結果會造成雖然 JavaScript 的變數值改了,但 畫面不會重新渲染,因為 Vue 不知道你改了 count

📌 需不需要使用 ref 的判斷

問題答案
這個值會在畫面上顯示出來嗎?✅ 用 ref()
它會被 v-ifv-forv-showv-model 等使用嗎?✅ 用 ref()
它只是用來計算、暫存、或在函式中傳遞?❌ 不用 ref()
它是一個物件(例如 user、form)?🔸 用 reactive() 會更方便

2. reactive()

  • 適合用來處理「物件 / 陣列」。
  • 不需要 .value,可以直接修改屬性。

範例:使用者物件

<script setup>
import { reactive } from "vue";

const user = reactive({
name: "Tom",
age: 20,
});

const growUp = () => {
user.age++;
};
</script>

<template>
<p>{{ user.name }} - {{ user.age }}</p>
<button @click="growUp">+1 歲</button>
</template>

📌 重點

  • reactive({}) 會回傳一個「Proxy 物件」。
  • 直接操作屬性即可觸發響應更新。

3. ref()reactive() 的差異

特性ref()reactive()
適合用來處理單一值(字串/數字/布林)物件、陣列
存取方式.value直接存取
模板中存取自動解開 .value直接使用
本質包裝一個值的物件物件/陣列的 Proxy

4. 特殊情況

1) 用 ref 包物件

const user = ref({ name: "Tom", age: 20 });
user.value.age++; // 需要透過 .value

2) 搭配解構(需注意)

如果對 reactive 物件解構,會失去響應性:

const user = reactive({ name: "Tom", age: 20 });
const { name } = user; // ❌ name 不再是響應式

解法 → 使用 toRefs()storeToRefs()(Pinia 常用):

import { toRefs } from "vue";
const { name, age } = toRefs(user); // ✅ 保持響應性

5. 小結

  • ref():單一值,存取用 .value
  • reactive():物件/陣列,直接操作屬性。
  • 解構 reactive 時要小心,避免失去響應性。
  • 如果擔心無法判斷什麼時候要使用 ref()reactive() ,可以全部都使用ref(),後續實戰經驗多了就知道什麼時候要使用reactive()