ref
不會遞歸地對 對象 或 數組 中的每個屬性或元素進行深度響應式處理。如果你需要遞歸處理嵌套屬性,reactive
是更適合的選擇。讓我通過具體的例子來展示這一點。
例子:ref
存儲對象和嵌套對象
1. 使用 ref
存儲嵌套對象:
import { createApp, ref } from 'vue';createApp({setup() {// 使用 ref 存儲對象,包含嵌套屬性const user = ref({name: 'Alice',profile: {age: 25,address: 'New York'}});// 修改嵌套屬性function updateUser() {user.value.profile.age = 26; // 修改嵌套對象的屬性}return {user, // 返回 user 對象給模板updateUser};}
}).mount('#app');
模板部分:
<div id="app"><p>Name: {{ user.value.name }}</p><p>Age: {{ user.value.profile.age }}</p><button @click="updateUser">Update Age</button>
</div>
問題:
在這個例子中,ref
用于存儲一個 對象,對象內有一個嵌套的 profile
對象。user.value.profile.age
是嵌套屬性,它應該是響應式的。但問題在于,ref
不會遞歸地對嵌套對象進行響應式處理。user.value.profile
并不是深度響應式的,而是淺響應式的。
這意味著,當你修改 user.value.profile.age
時,Vue 不會自動更新視圖,因為 profile
對象沒有被 深度響應式化。
解決方法:
如果我們希望 profile
對象的嵌套屬性(如 age
和 address
)也能觸發視圖更新,我們需要通過 reactive
來深度響應式化這個對象。
2. 使用 reactive
存儲嵌套對象:
import { createApp, reactive } from 'vue';createApp({setup() {// 使用 reactive 創建深度響應式對象const user = reactive({name: 'Alice',profile: {age: 25,address: 'New York'}});// 修改嵌套屬性function updateUser() {user.profile.age = 26; // 修改嵌套對象的屬性}return {user, // 返回 user 對象給模板updateUser};}
}).mount('#app');
模板部分:
<div id="app"><p>Name: {{ user.name }}</p><p>Age: {{ user.profile.age }}</p><button @click="updateUser">Update Age</button>
</div>
解釋:
- 在這個例子中,
reactive
用來將user
對象及其內部屬性(如profile
)深度響應式化。 - 現在,修改
user.profile.age
時,profile
對象 和age
屬性 都是 深度響應式的,因此視圖會自動更新。
總結:
ref
存儲 對象 或 數組 時,它只會 創建響應式引用,不會遞歸地對對象的嵌套屬性進行響應式處理。你需要使用.value
來訪問和修改對象的內容。如果對象有嵌套的屬性,ref
無法保證它們是響應式的,除非顯式地使用reactive
。reactive
會對 對象 及其所有 嵌套屬性 進行深度響應式處理,無需使用.value
,并且修改嵌套屬性時視圖會自動更新。
何時使用 ref
和 reactive
?
ref
適用于 基本數據類型(如number
、string
)以及 簡單的對象或數組,但你需要通過.value
來訪問和修改數據。reactive
適用于 復雜數據類型(如 對象 或 數組),并且會自動遞歸地將對象的每個屬性都變成響應式。