跳至主要内容

Vue 3 shallowRef 簡易介紹

簡介

在 Vue 3 中,我們通常使用 ref() 來建立響應式變數,但 ref() 內部是物件或陣列時,Vue 會深層追蹤所有屬性,這可能會影響效能。

shallowRef() 只追蹤「變數本身」,不追蹤內部物件的變化,適用於:

  • 大規模物件(API 回應資料、表格數據)
  • 不希望 Vue 監聽內部屬性的情境
  • 要手動控制更新的情境

ref 和 shallowRef 的差異

方法追蹤方式適用情境
ref()深層追蹤 (Deep Reactive)變數的內部屬性需要即時響應
shallowRef()僅追蹤變數本身 (Shallow Reactive)變數內容較大、變動頻率低、希望手動更新

ref 的問題:深層追蹤導致效能影響

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

const user = ref({
name: "Alice",
age: 25,
});

const updateAge = () => {
user.value.age += 1; // Vue 會深層監聽整個物件,影響效能
};
</script>

<template>
<div>
<p>姓名:{{ user.name }}</p>
<p>年齡:{{ user.age }}</p>
<button @click="updateAge">增加年齡</button>
</div>
</template>

user.value.age 變了,但 Vue 仍會檢查 user 整個物件是否變更,可能導致 不必要的重新渲染


shallowRef 提升效能

App.vue
<script setup>
import { shallowRef } from "vue";

const user = shallowRef({
name: "Alice",
age: 25,
});

const updateAge = () => {
user.value.age += 1; // ❌ Vue 不會自動重新渲染
};

const forceUpdate = () => {
user.value = { ...user.value }; // ✅ 需要手動觸發更新
};
</script>

<template>
<div>
<p>姓名:{{ user.name }}</p>
<p>年齡:{{ user.age }}</p>
<button @click="updateAge">增加年齡(不會更新)</button>
<button @click="forceUpdate">強制更新</button>
</div>
</template>

shallowRef() 內部屬性變更不會觸發 Vue 更新需要手動更新變數


shallowRef 和 ref 的效能比較

方法Vue 會自動追蹤內部屬性嗎?適用場景
ref()✅ 是頻繁更新的小型物件
shallowRef()❌ 否大量資料、API 回應、手動更新時

何時該用 shallowRef?

  • API 回應(JSON 結構大,不希望 Vue 深度追蹤)
  • 表格、清單數據(不希望每個改動都觸發 Vue 監聽)
  • 手動控制何時更新畫面