Vue Compute() wird nicht auf reaktiver Karte ausgelöst
P粉127901279
P粉127901279 2024-03-27 10:36:32
0
1
376

Ich habe ein reaktives um eine anfänglich leere Karte: const map =reactive({}); und ein const map =reactive({});,以及一个计算,它告诉如果地图有一个键“key”:const mapContainsKeyCompulated = Computed(() => map.hasOwnProperty("key"))compute

, das angibt, ob die Karte einen Schlüssel „key“ hat: const mapContainsKeyCompulated = Computed(() => map.hasOwnProperty("key")). Wenn ich die Karte ändere, werden die Berechnungen nicht aktualisiert.

Ich war einen Tag lang mit diesem Problem beschäftigt und habe es geschafft, ein Minimalbeispiel zu finden, das das Problem verdeutlicht:

<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>

Ich habe eine Reihe von Stackoverflow-Antworten und die Vue-Dokumentation gelesen, komme aber immer noch nicht dahinter.
  • Warum wird „mapContainsKeyCompulated“ nicht aktualisiert?
  • Wenn reaktiv Map:{{map}} das Hinzufügen oder Entfernen von Schlüsseln zur Karte nicht „verfolgt“, warum aktualisiert sich
  • (Zeile 14) dann so gut?
  • Wenn ich „map{} durch array[] und „hasOwnProperty“ durch „includes()“ ersetze, funktioniert es einwandfrei. Was ist der Unterschied?
  • Wie kann man dieses Problem lösen, ohne die hässliche „Watch“-Lösung zu verwenden (wobei „map.hasOwnProperty(key)“ wiederholt werden muss)?

EDIT: Wie @estus-flask erwähnte, handelt es sich hierbei um einen VueJS-Fehler, der in 3.2.46 behoben wurde. 🎜
P粉127901279
P粉127901279

Antworte allen(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) 将触发反应性。

Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage