創建不可變的響應式數據:readonly()
Vue 3 提供的 readonly() 函式可用來建立 不可變
的響應式數據,防止外部修改特定狀態。在某些情況下(如跨組件傳遞資料時),這能有效避免資料被意外改動。
🔹 基本用法
readonly() 會建立一個代理對象,使其內容變為只讀。
⚠️ 注意:如果來源本身是響應式資料,變更仍會同步反映在 readonly 版本中。
🔹 作用於 reactive()
物件
當 readonly() 作用於 reactive()
回傳的物件時,該物件的所有屬性皆會變成只讀。
🔹 搭配 toRefs() 的使用
readonly() 可以與 toRefs()
一起使用,將只讀物件轉換為獨立的響應式屬性,但這些屬性仍然是只讀的。
🔹 搭配 watch() 使用
readonly() 不影響資料的響應性,因此可以用於 watch() 中監聽其變化。
🔹 搭配 provide
/ inject 使用
在組件間傳遞資料時,使用 readonly() 可以保護資料不被子元件意外修改,保持狀態一致性。
父元件
子元件
📌 補充說明
readonly() 不會深層凍結物件(不是
deep freeze),但它會使所有屬性透過 Vue
proxy變得不可改變。
- 原始對象(如
ref 或
reactive)仍然可變,readonly 只是一個包裝。
- 若要完全避免狀態被修改,請搭配應用層邏輯或在程式碼設計中不暴露原始對象。
📚 參考資料
創建不可變的響應式數據:
readonly()Vue 3 提供的
readonly()函式可用來建立 不可變 的響應式數據,防止外部修改特定狀態。在某些情況下(如跨組件傳遞資料時),這能有效避免資料被意外改動。🔹 基本用法
<script setup> import { ref, readonly } from 'vue'; const count = ref(10); const readOnlyCount = readonly(count); count.value = 20; // ✅ 可以修改 readOnlyCount.value = 30; // ❌ 會報錯 (因為是只讀) </script>🔹 作用於
reactive()物件<script setup> import { reactive, readonly } from 'vue'; const user = reactive({ name: 'Jack', age: 25 }); const readOnlyUser = readonly(user); user.name = 'Tom'; // ✅ 原始對象仍可修改 readOnlyUser.name = 'Mike'; // ❌ 會報錯 (因為是 readonly) </script>🔹 搭配
toRefs()的使用<script setup> import { reactive, readonly, toRefs } from 'vue'; const user = reactive({ name: 'Jack', age: 25 }); const readOnlyUser = readonly(user); const { name, age } = toRefs(readOnlyUser); name.value = 'Tom'; // ❌ 會報錯 (因為是 readonly) </script>🔹 搭配
watch()使用<script setup> import { ref, readonly, watch } from 'vue'; const count = ref(0); const readOnlyCount = readonly(count); watch(readOnlyCount, (newVal) => { console.log('count 變更為:', newVal); }); count.value++; // ✅ 會觸發 watch readOnlyCount.value++; // ❌ 會報錯 </script>🔹 搭配
provide/inject使用父元件
<script setup> import { ref, provide, readonly } from 'vue'; const theme = ref('dark'); // 提供 readonly 版本的資料給子元件使用 provide('theme', readonly(theme)); </script> <template> <ChildComponent /> </template>子元件
<script setup> import { inject } from 'vue'; const theme = inject('theme'); console.log(theme.value); // ✅ 可讀取 "dark" theme.value = 'light'; // ❌ 會報錯 (因為是 readonly) </script>📌 補充說明
readonly()不會深層凍結物件(不是deep freeze),但它會使所有屬性透過 Vue proxy變得不可改變。ref或reactive)仍然可變,readonly只是一個包裝。📚 參考資料