444
1. 使用 Lodash 的
2. 使用
3. 使用
目錄
在 Vue 3 中,我們經常需要監視陣列中物件的變化。
然而,由於 Vue 的響應式系統的特性,直接使用 watch
可能無法正確檢測到這些變化。
本文將介紹三種常用的解決方案,並比較它們的優缺點。
問題描述
首先,讓我們看看為什麼直接使用 watch
可能會遇到問題:
const items = ref([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
]);
watch(items, (newItems, oldItems) => {
// newItems 和 oldItems 指向同一個物件
// 無法正確檢測變化
});
在這個例子中,newItems
和 oldItems
實際上指向同一個物件,因此我們無法比較它們的差異。
解決方案
1. 使用 Lodash 的 cloneDeep
方法
Lodash 的 cloneDeep
方法可以創建deep copy,包括處理循環引用。
<script setup>
import { ref, watch } from 'vue'
import _ from 'lodash'
const items = ref([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
])
let oldItemsSnapshot = _.cloneDeep(items.value)
watch(items, (newItems) => {
newItems.forEach((newItem, index) => {
const oldItem = oldItemsSnapshot[index]
if (oldItem && !_.isEqual(newItem, oldItem)) {
console.log(`Item changed: `, newItem)
}
})
oldItemsSnapshot = _.cloneDeep(newItems)
}, { deep: true })
</script>
2. 使用 JSON.parse(JSON.stringify())
這是一個簡單的方法,適用於不包含函數或循環引用的資料結構。
<script setup>
import { ref, watch } from 'vue'
const items = ref([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
])
let oldItemsSnapshot = JSON.parse(JSON.stringify(items.value))
watch(items, (newItems) => {
newItems.forEach((newItem, index) => {
const oldItem = oldItemsSnapshot[index]
if (oldItem && JSON.stringify(newItem) !== JSON.stringify(oldItem)) {
console.log(`Item changed: `, newItem)
}
})
oldItemsSnapshot = JSON.parse(JSON.stringify(newItems))
}, { deep: true })
</script>
3. 使用 structuredClone()
structuredClone()
是一個較新的 Web API,可以處理循環引用,但不支援函數。
<script setup>
import { ref, watch } from 'vue'
const items = ref([
{ id: 1, name: 'Item 1' },
{ id: 2, name: 'Item 2' }
])
let oldItemsSnapshot = structuredClone(items.value)
watch(items, (newItems) => {
newItems.forEach((newItem, index) => {
const oldItem = oldItemsSnapshot[index]
if (oldItem && JSON.stringify(newItem) !== JSON.stringify(oldItem)) {
console.log(`Item changed: `, newItem)
}
})
oldItemsSnapshot = structuredClone(newItems)
}, { deep: true })
</script>
比較與選擇
1.Lodash cloneDeep
:
- 優點:功能最完整,可處理複雜資料結構。
- 缺點:需要額外引入。
2.JSON.parse(JSON.stringify())
:
- 優點:簡單,不需要外部依賴。
- 缺點:無法處理函數、
undefined
、Symbol
或循環引用。
3.structuredClone()
:
- 優點:原生 API,可處理循環引用。
- 缺點:不支援函數,瀏覽器兼容性問題。
選擇建議:
- 複雜資料結構:使用 Lodash。
- 簡單資料結構且考慮瀏覽器兼容性:使用
JSON.parse(JSON.stringify())
。 - 現代瀏覽器環境下的一般用途:使用
structuredClone()
。
結論
在 Vue 3 中watch物件陣列變化時,選擇適當的方法非常重要。根據你的專案需求、資料複雜度和目標瀏覽器,選擇最適合的解決方案。無論哪種方法,都能幫助你更有效地追蹤和回應資料變化。
探索更多來自 雖然沒準備什麼資料 的內容
Subscribe to get the latest posts sent to your email.