Laden Sie Firestore-Daten in Komponenten, bevor Sie sie mit Vuefire rendern
P粉790187507
2023-08-29 15:05:47
<p>Ich versuche, eine Personentabelle mit Namen und Profilbildern zu füllen. Der Name wird aus der Firestore-Datenbank abgeleitet und vom Bild verwendet, um verwandte Bilder im Firebase-Bucket zu finden. </p>
<p>Ich habe stundenlang Videos angeschaut und fast hundert Artikel durchgesehen, daher enthält mein Beispielcode Ausschnitte von jedem Code, da ich jede Kombination ausprobiert und eine Mischung erhalten habe, aber keine erfolgreichen Ergebnisse erzielt habe. </p>
<p>Im aktuellen Zustand, der nur minimale Fehler zurückgibt, kann ich die Tabelle erfolgreich mit den Namen füllen, allerdings schlägt das Extrahieren des Profilbilds innerhalb derselben Komponente fehl. Der für das Profilbild verwendete Wert wurde aktualisiert, jedoch von einem Platzhalterwert auf <code>undefiniert</code>. </p>
<p><strong>GamePlanner.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><template>
<div>
<Feld />
<Bank />
<!-- <Spannung>
<template #default>
<PlanSummary />
<!-- </template>
<template #fallback>
<div class="loading">Loading...</div>
</template>
</Suspense>
</div>
</template>
</pre>
<p><strong>PlanSummary.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><template>
<div class="summaryContainer">
<div class="inningTableContainer">
<table class="inningTable">
<tbody>
<!-- <Spannung> -->
<!-- <template #default> -->
<PlayerRow v-for="Spieler in spieler.value" :key="player.id" :player="(Spieler als Spieler)" />
<!-- </template> -->
<!-- <template #fallback>
<tr data-playerid="0">
<img class="playerImage" src="https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50" />
Spieler werden geladen...
<span class="playerNumber">00</span>
</tr>
</template> -->
<!-- </Suspense> -->
</tbody>
</table>
</div>
</div>
</template>
<script setup lang="ts">
import { berechnet, onErrorCaptured, ref } aus „vue“;
import { useFirestore, useCollection } aus „vuefire“;
{ Sammlung } aus „Firebase/Firestore“ importieren;
import { Player, Inning } from "@/definitions/GamePlanner";
importiere PlayerRow aus „./PlayerRow.vue“;
const db = useFirestore();
const gamePlanID = "O278vlB9Xx39vkZvIsdP";
// const player = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// const player = ref(useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// Unbehandelter Fehler während der Ausführung des Scheduler-Flushes
// Nicht abgefangen (im Versprechen) DOMException: 'insertBefore' konnte nicht auf 'Node' ausgeführt werden: Der Knoten, vor dem der neue Knoten eingefügt werden soll, ist kein untergeordnetes Element dieses Knotens.
const player = ref();
player.value = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// Scheinbar Endlosschleife mit „onServerPrefetch wird aufgerufen, wenn keine aktive Komponenteninstanz vorhanden ist, der zugeordnet werden kann.“
// Rendert 5 (??) undefinierte Spieler
// Ein Fehler wird angezeigt: Uncaught (im Versprechen) TypeError: Eigenschaften von undefiniert können nicht gelesen werden (liest „Teilzeichenfolge“)
// constplayers = berechnet(() => useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// onErrorCaptured((error, vm, info) => {
// console.log("Fehler beim Laden der Zusammenfassungskomponente: ", Fehler, "vm: ", vm, "info: ", info);
// Fehler werfen;
// });
</script>
</pre>
<p><strong>PlayerRow.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><template>
<tr :key="player2.id" :data-playerid="player2.id">
<td>
<img class="playerImage" :src="playerPictureURL" />
{{ player2.nickname || Spieler2.Vorname + " " + Spieler2.Nachname }}
<span class="playerNumber">{{ player2.playerNumber }}</span>
</td>
</tr>
</template>
<script lang="ts" Setup>
import { ref, PropType, berechnet, onMounted, watch } aus „vue“;
import { useFirebaseStorage, useStorageFileUrl } aus „vuefire“;
import { ref as storageRef } from 'firebase/storage';
import { Player, Inning } from "@/definitions/GamePlanner";
const fs = useFirebaseStorage();
const props = defineProps({
'player': { type: Object as PropType<Player>, erforderlich: true },
// 'Innings': Array<Inning>
});
const player2 = ref(props.player);
// const innings = berechnet(() => props.innings);
// const playerPictureURL = berechnet(() => {
// const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
// const playerPictureResource = storageRef(fs, `playerPictures/${playerPictureFilename}`);
// useStorageFileUrl(playerPictureResource).url.value als String zurückgeben;
// });
// const playerPictureURL = ref(() => {
// const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
// const playerPictureResource = storageRef(fs, `playerPictures/${playerPictureFilename}`);
// useStorageFileUrl(playerPictureResource).url.value als String zurückgeben;
// });
const playerPictureURL = ref("https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50");
asynchrone Funktion getPlayerPictureURL() {
console.log("PlayerRow.ts getPlayerPictureURL");
const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
const playerPictureResource = waiting storageRef(fs, `playerPictures/${playerPictureFilename}`);
playerPictureURL.value = warte auf useStorageFileUrl(playerPictureResource).url.value als String;
}
onMounted(() => {
console.log("PlayerRow.ts onMounted");
getPlayerPictureURL();
});
watch(playerPictureURL, (newVal, oldVal) => {
console.log("PlayerRow.ts watch playerPictureURL");
console.log("newVal: " + newVal);
console.log("oldVal: " + oldVal);
});
</script>
</pre>
<p>我的印象是 <code><Suspense></code> 需要包装 <code><PlayerRow></code> 组件,因为我正在使用 <code>storageRef</code> 和 < code>useStorageUrl</code> 方法,但它似乎引入了更多问题.根据 vuefire但是尝试立即调用它们不会产生立即/实际结果.</p>
<p><strong>相关软件包版本</strong></p>
<pre class="brush:json;toolbar:false;">{
"vue": "^3.2.45"
"firebase": "^9.15.0",
"Typoskript": "^4.9.3",
"vite": "^4.0.0",
„vue-router“: „^4.1.6“,
"vue-tsc": "^1.0.11",
„vuefire“: „3.0.0-beta.6“
}
</pre></p>
根据这个文档我们应该使用
useCollection
包含collection
作为参数,如下所示:我发现您正在以正确的方式使用它,但您可以将其直接分配给
players
变量,而不是分配给ref
。当您尝试使用此反应式对象作为ref
对象的值时,这是不受支持的。您可以通过更改此行来解决您的问题:
致:
有关此主题的更多信息,您可以浏览以下文档