ref 與 reactive

比較

特性 ref() reactive()
適用類型 基本類型(數值、字串、布林)、物件、陣列 僅適用於物件與陣列
訪問屬性方式 需要 .value 可直接存取
深層響應式 否,內部物件需額外處理 是,內部屬性皆為響應式
解構後的反應性 否,會失去響應性 是(可搭配 toRefs() 保留響應性)

ref()

說明

ref() 用來建立一個響應式資料容器,適用於基本型別或單一變數狀態。
使用時需透過 .value 存取值,Vue 會自動追蹤 .value 的變化並更新畫面。

範例:

import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);
    const message = ref("Hello");

    const increment = () => {
      count.value++;
    };

    return { count, message, increment };
  }
};

說明:

  • ref(0) 回傳的是一個響應式物件,值存放在 .value 屬性中。
  • 修改 .value 後,Vue 會自動重新渲染畫面。

全域 API 寫法(僅適用於 CDN)

在使用 Vue CDN 版本(非模組化開發)時,可以使用 Vue.ref(),無需 import。

範例:

<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
<script>
  const { createApp } = Vue;

  createApp({
    setup() {
      const count = Vue.ref(0);
      return { count };
    }
  }).mount('#app');
</script>

說明:

  • 僅適用於 <script> 引入 Vue 的瀏覽器環境。
  • 不建議用於模組化專案。
  • 若 Vue 為全域變數,可透過 Vue.ref() 使用。

模組化 ESM 寫法(官方推薦)

使用 Vite、Webpack、Vue CLI 等模組化開發環境時,請使用 ESM 模組語法:

import { ref } from 'vue';
const count = ref(0);

範例:

import { createApp, ref } from 'vue';
import App from './App.vue';

const app = createApp(App);
app.mount('#app');

優點:

  • 僅載入需要的 API(如 ref),減少依賴體積。
  • 支援模組化、效能佳、官方推薦。

ref 使用場景與注意事項

比較項目 Vue.ref(0)(全域 API) import { ref }(ESM 模組)
適用環境 Vue CDN、Vue 2.7+ 全域 API Vite、Webpack 等模組化開發
是否需要 import
是否適合模組化
效能與體積 可能較大且慢 更小更快
官方推薦

總結:

  • 小型專案 / 練習可使用全域 API。
  • 實務專案建議使用 ESM 模組化方式搭配建構工具。

reactive()

說明

reactive() 用來建立物件或陣列的完整響應式狀態。
適合處理多個欄位的資料結構,並且不需使用 .value

範例:

import { reactive } from 'vue';

export default {
  setup() {
    const user = reactive({
      name: 'Jack',
      age: 30
    });

    const updateName = () => {
      user.name = 'Tom';
    };

    return { user, updateName };
  }
};

說明:

  • reactive() 適用於物件、陣列,內部屬性會自動遞迴轉為響應式。
  • 解構時響應性會遺失,請搭配 toRefs() 使用:
import { reactive, toRefs } from 'vue';

setup() {
  const state = reactive({ count: 0 });
  return { ...toRefs(state) }; // 保持解構後仍具響應性
}

官方文件連結