Charger les données Firestore dans les composants avant le rendu avec Vuefire
P粉790187507
2023-08-29 15:05:47
<p>J'essaie de remplir un tableau de personnes avec des noms et des photos de profil. Le nom est dérivé de la base de données Firestore et est utilisé par l'image pour rechercher des images associées dans le compartiment Firebase. </p>
<p>J'ai regardé des heures de vidéos et parcouru près d'une centaine d'articles. Mon exemple de code contient donc des extraits de chaque code, car j'ai essayé toutes les combinaisons et obtenu un mélange, mais sans succès. </p>
<p>Dans l'état actuel qui renvoie des erreurs minimes, je parviens à remplir le tableau avec les noms, mais dans le même composant, il ne parvient pas à extraire la photo de profil. La valeur utilisée pour la photo de profil a été mise à jour, mais elle a été mise à jour d'une valeur d'espace réservé vers <code>undefined</code>. </p>
<p><strong>GamePlanner.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><template>
<div>
<Champ />
<Banc />
<!-- <Suspense>
<modèle #par défaut>
<Résumé du plan />
<!-- </modèle>
<modèle #fallback>
<div class="chargement">Chargement...</div>
</modèle>
</Suspense>
</div>
</modèle>
≪/pré>
<p><strong>PlanSummary.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><template>
<div class="summaryContainer">
<div class="inningTableContainer">
<table class="inningTable">
<corps>
<!-- <Suspense> --->
<!-- <modèle #default> --->
<PlayerRow v-for="joueur dans Players.value" :key="player.id" :player="(joueur en tant que joueur)" />
<!-- </modèle> --->
<!-- <modèle #fallback>
<tr data-playerid="0">
<img class="playerImage" src="https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50" />
Chargement des joueurs...
<span class="playerNumber">00</span>
≪/tr>
</modèle> --->
<!-- </Suspense> --->
</tcorps>
</tableau>
</div>
</div>
</modèle>
<configuration du script lang="ts">
import { calculé, onErrorCaptured, ref } depuis "vue" ;
importer { useFirestore, useCollection } depuis "vuefire" ;
importer {collection} depuis "firebase/firestore" ;
importer { Player, Inning } depuis "@/definitions/GamePlanner" ;
importer PlayerRow depuis "./PlayerRow.vue" ;
const db = useFirestore();
const gamePlanID = "O278vlB9Xx39vkZvIsdP";
// const joueurs = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// const joueurs = ref(useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// Erreur non gérée lors de l'exécution du vidage du planificateur
// Non intercepté (promis) DOMException : échec de l'exécution de 'insertBefore' sur 'Node' : le nœud avant lequel le nouveau nœud doit être inséré n'est pas un enfant de ce nœud.
const joueurs = ref();
joueurs.value = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// Une boucle apparemment infinie avec "onServerPrefetch est appelée lorsqu'il n'y a aucune instance de composant actif à associer."
// Rend 5 (??) joueurs non définis
// Une erreur affichée : Non capturé (promis) TypeError : Impossible de lire les propriétés d'undéfini (lecture de 'sous-chaîne')
// const joueurs = calculé(() => useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// onErrorCaptured((erreur, machine virtuelle, info) => {
// console.log("Erreur de chargement du composant Résumé : ", erreur, "vm : ", vm, "info : ", info);
// renvoie une erreur ;
// });
</script>
≪/pré>
<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" />
{{ joueur2.surnom || joueur2.premierNom + " " + joueur2.nom de famille }}
<span class="playerNumber">{{ player2.playerNumber }}</span>
</td>
≪/tr>
</modèle>
<script lang="ts" configuration>
import { ref, PropType, calculated, onMounted, watch } depuis "vue" ;
importer { useFirebaseStorage, useStorageFileUrl } depuis "vuefire" ;
importer { ref as storageRef } depuis 'firebase/storage' ;
importer { Player, Inning } depuis "@/definitions/GamePlanner" ;
const fs = useFirebaseStorage();
const props = définirProps({
'player' : { type : Objet en tant que PropType<Player>, obligatoire : true },
// 'manches' : Array<Inning>
});
const joueur2 = ref(props.player);
// const innings = calculé(() => props.innings);
// const playerPictureURL = calculé(() => {
// const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
// const playerPictureResource = storageRef(fs, `playerPictures/${playerPictureFilename}`);
// renvoie useStorageFileUrl(playerPictureResource).url.value sous forme de chaîne ;
// });
// const playerPictureURL = ref(() => {
// const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
// const playerPictureResource = storageRef(fs, `playerPictures/${playerPictureFilename}`);
// renvoie useStorageFileUrl(playerPictureResource).url.value sous forme de chaîne ;
// });
const playerPictureURL = ref("https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50");
fonction asynchrone getPlayerPictureURL() {
console.log("PlayerRow.ts getPlayerPictureURL");
const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
const playerPictureResource = wait storageRef(fs, `playerPictures/${playerPictureFilename}`);
playerPictureURL.value = wait useStorageFileUrl(playerPictureResource).url.value sous forme de chaîne ;
}
onMounted(() => {
console.log("PlayerRow.ts onMounted");
getPlayerPictureURL();
});
watch(playerPictureURL, (newVal, oldVal) => {
console.log("PlayerRow.ts regarde playerPictureURL");
console.log("newVal:" + newVal);
console.log("oldVal:" + oldVal);
});
</script>
≪/pré>
<p>我的印象是 <code><Suspense></code> <code><PlayerRow></code> 组件,因为我正在使用 <code>storageRef</code> 和 < code>useStorageUrl</code> Il s'agit d'une vuefire.是尝试立即调用它们不会产生立即/实际结果。</p>
<p><strong>相关软件包版本</strong></p>
<pre class="brush:json;toolbar:false;">{
"vue" : "^3.2.45"
"firebase": "^9.15.0",
"dactylographié": "^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>
Selon cette documentation nous devrions utiliser
useCollection
包含collection
comme paramètre comme ceci :Je vois que vous l'utilisez correctement, mais vous pouvez l'attribuer directement à la valeur de l'objet
players
变量,而不是分配给ref
。当您尝试使用此反应式对象作为ref
, ce qui n'est pas pris en charge.Vous pouvez résoudre votre problème en modifiant cette ligne :
À :
Pour plus d'informations sur ce sujet, vous pouvez parcourir les documents
suivants