簡體   English   中英

在使用 Vuefire 渲染之前在組件中加載 Firestore 數據

[英]Load Firestore Data in Component Before Render Using Vuefire

我正在嘗試用他們的名字和個人資料圖片填充一張人表。 名稱源自 Firestore 數據庫,圖片使用名稱在 Firebase Storage 存儲桶中查找相關圖片。

我已經看了幾個小時的視頻,並且已經搜索了將近一百篇文章,所以我的示例代碼包含了每篇文章的片段,因為我一直在嘗試每一種組合並得到混合但不成功的結果。

在返回最少錯誤的當前狀態下,我能夠成功地用名稱填充表,但是在同一組件中它無法提取個人資料圖片。 用於個人資料圖片的值已更新,但它從占位符值更新為undefined

GamePlanner.vue

<template>
    <div>
    <Field />
    <Bench />
    <!-- <Suspense>
        <template #default> -->
            <PlanSummary />
        <!-- </template>
        <template #fallback>
            <div class="loading">Loading...</div>
        </template>
    </Suspense> -->
    </div>
</template>

計划摘要.vue

<template>
    <div class="summaryContainer">
        <div class="inningTableContainer">
            <table class="inningTable">
                <tbody>
                    <!-- <Suspense> -->
                        <!-- <template #default> -->
                            <PlayerRow v-for="player in players.value" :key="player.id" :player="(player as Player)" />
                        <!-- </template> -->

                        <!-- <template #fallback>
                            <tr data-playerid="0">
                                <img class="playerImage" src="https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50" />
                                Loading players...
                                <span class="playerNumber">00</span>
                            </tr>
                        </template> -->
                    <!-- </Suspense> -->
                </tbody>
            </table>
        </div>

    </div>
</template>

<script setup lang="ts">
import { computed, onErrorCaptured, ref } from "vue";
import { useFirestore, useCollection } from "vuefire";
import { collection } from "firebase/firestore";
import { Player, Inning } from "@/definitions/GamePlanner";
import PlayerRow from "./PlayerRow.vue";

const db = useFirestore();
const gamePlanID = "O278vlB9Xx39vkZvIsdP";

// const players = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));

// const players = ref(useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));

// Unhandled error during execution of scheduler flush
// Uncaught (in promise) DOMException: Failed to execute 'insertBefore' on 'Node': The node before which the new node is to be inserted is not a child of this node.
const players = ref(); 
players.value = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));

// Seeminly infinite loop with "onServerPrefetch is called when there is no active component instance to be associated with."
// Renders 5 (??) undefined players
// One error shown: Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'substring')
// const players = computed(() => useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));

// onErrorCaptured((error, vm, info) => {
//     console.log("Error loading Summary component: ", error, "vm: ", vm, "info: ", info);
//     throw error;
// });
</script>

PlayerRow.vue

<template>
    <tr :key="player2.id" :data-playerid="player2.id">
        <td>
            <img class="playerImage" :src="playerPictureURL" />
            {{ player2.nickname || player2.firstName + " " + player2.lastName }}
            <span class="playerNumber">{{ player2.playerNumber }}</span>
        </td>
    </tr>
</template>

<script lang="ts" setup>
import { ref, PropType, computed, onMounted, watch } from "vue";
import { useFirebaseStorage, useStorageFileUrl } from "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>, required: true },
    // 'innings': Array<Inning>
});
const player2 = ref(props.player);

// const innings = computed(() => props.innings);

// const playerPictureURL = computed(() => {
//     const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
//     const playerPictureResource = storageRef(fs, `playerPictures/${playerPictureFilename}`);
//     return useStorageFileUrl(playerPictureResource).url.value as string;
// });
// const playerPictureURL = ref(() => {
//     const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
//     const playerPictureResource = storageRef(fs, `playerPictures/${playerPictureFilename}`);
//     return useStorageFileUrl(playerPictureResource).url.value as string;
// });

const playerPictureURL = ref("https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50");
async function getPlayerPictureURL() {
    console.log("PlayerRow.ts getPlayerPictureURL");
    const playerPictureFilename = `${player2.value.firstName.substring(0,1)}${player2.value.lastName}.png`.toLowerCase();
    const playerPictureResource = await storageRef(fs, `playerPictures/${playerPictureFilename}`);
    playerPictureURL.value = await useStorageFileUrl(playerPictureResource).url.value as 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>

我的印象是<Suspense>需要包裝<PlayerRow>組件,因為我正在使用storageRefuseStorageUrl方法,但它似乎引入了更多問題。 根據 vuefire 文檔並檢查代碼本身的定義,它們似乎不是異步的,但是嘗試立即調用它們不會產生即時/實際結果。

相關包版本

{
    "vue": "^3.2.45"
    "firebase": "^9.15.0",
    "typescript": "^4.9.3",
    "vite": "^4.0.0",
    "vue-router": "^4.1.6",
    "vue-tsc": "^1.0.11",
    "vuefire": "3.0.0-beta.6"
}

根據此文檔,我們應該使用useCollection並將collection作為參數包含在內,如下所示:

const todos = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`))

我看到你正在以正確的方式使用它,而不是分配給ref你可以直接將它分配給players變量。 當您嘗試將此反應對象用作ref對象的值時,這是不受支持的。

您可以通過更改此行來解決您的問題:

const players = ref(); 
players.value = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));

到:

const players = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));

有關此主題的更多信息,您可以閱讀以下文檔

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM