在 Vue 的使用中你可能會看到 ref 跟 reactive,
這是 Composition API 的核心,讓資料具備響應式。
但平平都是用來做變數的引用,到底差在哪裡確實是會讓人有點懷疑,
此篇文章就是用來釐清何種情況使用為較優解。
[2026/02/10 更新]
關於文中一些可能導致誤解的觀念將會並補充正確觀念
為避免第一次使用 Vue 的人看不懂
這邊還是簡單講解一下怎麼看響應式函數
註解
- 宣告一個常數,可以讓我們後續使用。
- 為這個常數賦予名稱。
- 響應式函數並接收一個參數初始值。
- 初始值為數字 0。
所以上面這句可以被理解為:
我們宣告了一個常數叫做 count,它是一個響應式的物件,裡面存了一個初始值 0。
言傳不如身教,話不多說,直接上手開始練習吧。
ref<script setup>
import { ref } from 'vue'
const year = ref(2025)
console.log(year.value) // 2025
</script>
<template>
<h1>{{ year }}</h1>
</template>
reactive<script setup>
import { reactive } from 'vue'
const date = reactive({year:2025})
console.log(date.year) // Proxy(Object) {year: 2025}
</script>
<template>
<h1>{{ date.year }}</h1>
</template>
ref 或 reactive 嗎?先說結論,如果你要 資料響應式變化 那就要用。
當你在模板中使用了一個 ref,然後改變了這個 ref 的值時,Vue 會自動檢測到這個變化,
並且相應地更新 DOM。
這是通過一個基於依賴追蹤的響應式系統實現的。
當一個組件首次渲染時,Vue 會追蹤在渲染過程中使用的每一個 ref。
然後,當一個 ref 被修改時,它會觸發追蹤它的組件的一次重新渲染。 - 為什麼要使用 ref?
在使用上單一值會使用 ref ,而遇到物件時用 reactive 會更好,
但是! 其實你全都用 ref 也無所謂,後面會講為什麼。
ref 可以接受任意資料型態包含物件,
但通常會使用基本資料類型 ( Primitive data types )
reactive 只能接受物件類型 ( Reference data types )
[2026/02/10 更新]
這邊補充一下 官方雖然推薦全用 ref 也無所謂,
但最後還是會補充一下不同情境下可以考慮用 reactive
.value ?
我相信不管是第一次使用 Vue 或是使用一陣子的朋友都會覺得這個 .value ,
是一個很討厭的東西,都 2025 了要引用變數居然還要 .value 。
簡單來說就是由於原生 JavaScript 的限制,
我們需要透過 value 讓 Vue 有一個機會追蹤物件屬性變更,
但在這篇我們還不會過多講解這件事,
在後面響應式核心篇會再深入講解,讓我們銜接到 Alien-signals 時可以有更好的了解。
<template> 使用無須 .value?Vue 會自動解包 模板中的響應式物件:
注意,在模板中使用
ref時,我們不需要附加.value。
為了方便起見,當在模板中使用時,ref會自動解包 - ref()
reactive 就這麼沒人要嗎?
確實 ref 就足以應付大部分的場景,不過這邊我們可以來看一段 code。
<script setup>
import { ref } from 'vue';
const article = ref({
author: 'Yanya',
version: '3.5.0',
title: 'Progressive JavaScript Framework'
})
function updateVersion(){
article.value.version = '3.6.0'
}
</script>
<template>
<h1>{{article.title}}</h1>
<h2>Author : {{article.author}}</h2>
<p>version : {{article.version}}</p>
<button @click="updateVersion">點我更新版本</button>
</template>
這邊可以看到如果我用 ref 的話我就要 article.value.version 才有辦法更新裡面的屬性,
老實說真的有點煩。
於是我們稍微調整一下
+const article = reactive({
-const article = ref({
author: 'Yanya',
version: '3.5.0',
title: 'Progressive JavaScript Framework'
})
function updateVersion(){
+ article.value.version = '3.6.0'
- article.version = '3.6.0'
}
確實阿,會乾淨一點,那如果我今天多加一個狀況,我的物件裡面有 35 個屬性呢?
const article = reactive({
author: 'Yanya',
version: '3.5.0',
title: 'Progressive JavaScript Framework'
+ // 略...
})
function updateVersion(){
article.version = '3.6.0';
+ article.author = 'Evan';
+ article.title = 'Ref vs Reactive';
+ // 略...
}
聰明的你可能會想說,那不然我直接賦予他新的物件
不能替換整個對象:由於 Vue 的響應式跟蹤是通過屬性訪問實現的,因此我們必須始終保持對響應式對象的相同引用。這意味著我們不能輕易地“替換”響應式對象,因為這樣的話與第一個引用的響應性連接將丟失 - reactive() 的局限性
那我要怎麼做 QQ
這邊的話我們可以善用 Object.assign 將淺層物件複製到目標物件上
const article = reactive({
author: 'Yanya',
version: '3.5.0',
title: 'Progressive JavaScript Framework'
// 略...
})
+ const newInfo ={version:'3.6.0', author:'Evan', title:'Ref vs Reactive'}
function updateVersion(){
- article.version = '3.6.0';
- article.author = 'Evan';
- article.title = 'Ref vs Reactive';
+ Object.assign(article,newInfo)
}


[2026/02/10 更新]
各位應該也可以發現reactive無法輕易替換整個對象的原因就是他不是這樣設計的,reactive是用來做深度 proxy 的狀態物件,讓你可以修改裡面單一欄位內容或資料結構
如果要替換整個物件,建議用ref

如果我們今天需要用一個響應式物件跟模板連接,
為了避免和一般 ref 搞混,可能會嘗試在名稱上加上一個 Ref,
用來表示這不是 Primitive Data,而是 Instance 或 HTMLElement,例如 xxRef = ref('') 。
然後模板區域使用它,還要 ref="inputRef",這樣有點繞遠路的感覺。
在 3.5 時推出了 useTemplateRef(),主要是我們可以傳入自定義名稱,
然後模板區域直接 ref="input" 。
就我自己個人來講, 我會把需要綁定模板去做一些操作, 例如 .show .on ,
那我就會使用 useTemplateRef + InstanceType,這樣很好的展示出跟原始數據型態的 ref 差異
推薦使用時機 :
當你想要自定義 template ref 的名稱時可以使用
今天我們正式進入響應式系統篇章,為了打好基礎,響應式篇章會花比較大的篇幅做講解,
也透過了實際使用來了解 ref 和 reactive 的語法差異。
講解為什麼官方推薦使用 ref() 作為聲明響應式變數的 API,
經由實際案例來了解 reactive 的限制與優勢,
補充了 useTemplateRef 的使用方法。
可以看到官方所說的 reactive 的限制較多,包含傳入的值有限類型,
不能輕易替換物件值,解構將會失去響應式
由於這些限制,我們建議使用
ref()作為聲明響應式狀態的主要 API。
所以結論就是使用 ref 作為響應式變數的引用在大多情況是較好的解, 除非你要深層的監聽物件內部屬性, 或是把多個相依賴的 ref 組合成一個物件, 那就可以考慮用 reactive
[2026/02/10 更新]
關於這個結論是比較粗淺的解釋,這邊先感謝 Astolfo 福大幫我釐清了很多觀念
首先是關於ref跟reactive各自的使用情境//----------------- // ref //----------------- const name = ref<string>(''); // 單一值 const user = ref<User>(); // 整個物件會被替換 const state = ref<State>({ type: 'idle' }); // 狀態模型 //----------------- // reactive //----------------- const form = reactive({ name: '', address: '' }); // 一組相關的資料且不應該被整個換掉 form.name = 'John'; const staff = reactive({ /* 宣告資料結構 */ profile: { username: 'john', address: { city: 'Taipei' } }, roles: ['admin', 'user'] }); staff.profile.username = 'jane'; // 修改巢狀屬性看過上面這些範例,可以再來補充一下,因為 ref 是採深層遞迴,且遇到物件
就會轉 reactive 並變成 proxy 物件那如果裡面超級多層有夠大包又深,
那每層都要包 proxy ,就會造成效能損耗,因為裡面每個變動都會更新響應式物件
如果是這種大物件,可以考慮用 shallowRef() 控制邊界進行淺層響應
總而言之 ref 跟 reactive 都有各自被設計出來的理由,雖然官方推薦先用 ref
但還是可以根據不同狀況下去思考要用哪種 API
如果你喜歡這個系列或是想看我發瘋,歡迎按下 訂閱 一起走完這三十天吧。


以前剛接觸 Vue3 的時候也覺得 .value 很煩人...
不過後來發現 .value 可以很好的和一般狀態區分,知道目前是在存取響應式狀態還是一般狀態 ~
所以我比較支持全部使用 ref XD
另外~ ref 也是預設深層監聽物件內部屬性的唷 !
感謝回覆! 我個人也是覺得各有各的好處
沒錯~ ref 也是有支援深層監聽的!
在 Vue 過氣前要學的第六件事 - 響應式到底為什麼那麼重要 中,
也有一小段篇幅是在講解 ref 原始碼內部是怎麼處理的!
歡迎對這部分有興趣的朋友可以前往文章看看我怎麼發瘋哈哈
梗圖很有料XD 我反而比較好奇哪來這麼多素材 (重點誤
蠻多 gif 都是來自 7tv
至於其他的都是活網仔的經驗 XDD