我在最初為空的地圖周圍有一個反應性:const map =reactive({});
,以及一個計算,它告訴如果地圖有一個鍵「key」:const mapContainsKeyCompulated = Computed(() => map.hasOwnProperty("key"))
。當我更改地圖時,計算結果不會更新。
我在這個問題上堅持了一天,並設法想出了一個演示該問題的最小示例:
<script setup> import {computed, reactive, ref, watch} from "vue"; const map = reactive({}); const key = "key"; const mapContainsKeyComputed = computed(() => map.hasOwnProperty(key)) const mapContainsKeyWatched = ref(map.hasOwnProperty(key)); watch(map, () => mapContainsKeyWatched.value = map.hasOwnProperty(key)) </script> <template> Map: {{map}} <br/> Computed: does map contain "key"? {{mapContainsKeyComputed}} <br/> Watch: does map contain key? {{mapContainsKeyWatched}} <br/> <button @click="map[key] = 'value'">add key-value</button> </template>
我已經閱讀了一堆 stackoverflow 答案和 Vue 文檔,但我仍然無法弄清楚。
Map:{{map}}
(第14行)更新得很好? 編輯:如 @estus-flask 所提到的,這是 3.2.46 中修復的 VueJS 錯誤。
Vue 反應性需要明確支援反應式物件方法。
hasOwnProperty
是相當低級的,因此它已經有一段時間不受支援了。如果沒有支持,map.hasOwnProperty(key)
會嘗試存取非反應性原始物件上的key
,並且不會觸發反應性,因此第一個計算 呼叫不會設定可以在下一次
map
更改時觸發的偵聽器。解決此問題的一種方法是首先定義
key
(如另一個答案中所建議的),這是使反應性在 Vue 2 和 3 中工作的傳統方法:另一種方法是存取響應式物件上缺少的
key
屬性:另一種方法是使用
in
運算子。由於 Vue 3 使用Proxy
進行回應,因此可以透過has
trap 偵測到屬性被存取:對
hasOwnProperty
的支援已最近在 3.2.46 中添加,因此問題中的程式碼應該可以在最新的 Vue 版本中使用。map
並不是真正的地圖。如果使用Map
,這在任何 Vue 3 版本中都會有所不同,Vue 支援它,並且預計map.has(key)
將觸發反應性。