搜尋

首頁  >  問答  >  主體

Vue Compute() 未在反應式地圖上觸發

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

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

P粉127901279P粉127901279241 天前374

全部回覆(1)我來回復

  • P粉668146636

    P粉6681466362024-03-28 00:34:51

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

    回覆
    0
  • 取消回覆