Vue Compute() 未在反應式地圖上觸發
P粉127901279
P粉127901279 2024-03-27 10:36:32
0
1
394

我在最初為空的地圖周圍有一個反應性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 文檔,但我仍然無法弄清楚。

  • 為什麼 mapContainsKeyCompulated 沒有更新?
  • 如果反應式不「追蹤」在地圖上新增或刪除鍵,為什麼Map:{{map}}(第14行)更新得很好?
  • 當我用 array[] 取代 map{} 並將「hasOwnProperty」替換為「includes()」時,它運作正常。有什麼不同?
  • 如何解決這個問題,而不需要使用醜陋的「watch」解決方案(其中「map.hasOwnProperty(key)」必須重複)?

編輯:如 @estus-flask 所提到的,這是 3.2.46 中修復的 VueJS 錯誤。

P粉127901279
P粉127901279

全部回覆(1)
P粉668146636

Vue 反應性需要明確支援反應式物件方法。 hasOwnProperty 是相當低級的,因此它已經有一段時間不受支援了。如果沒有支持,map.hasOwnProperty(key) 會嘗試存取非反應性原始物件上的key,並且不會觸發反應性,因此第一個計算 呼叫不會設定可以在下一次map 更改時觸發的偵聽器。

解決此問題的一種方法是首先定義 key (如另一個答案中所建議的),這是使反應性在 Vue 2 和 3 中工作的傳統方法:

const map = reactive({ key: undefined })

另一種方法是存取響應式物件上缺少的 key 屬性:

const mapContainsKeyComputed = computed(() => map[key] !== undefined)

另一種方法是使用 in 運算子。由於 Vue 3 使用 Proxy 進行回應,因此可以透過 has trap 偵測到屬性被存取:

const mapContainsKeyComputed = computed(() => key in map)

hasOwnProperty 的支援已最近在 3.2.46 中添加,因此問題中的程式碼應該可以在最新的 Vue 版本中使用。

map 並不是真正的地圖。如果使用 Map,這在任何 Vue 3 版本中都會有所不同,Vue 支援它,並且預計 map.has(key) 將觸發反應性。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板