Vuefire でレンダリングする前に Firestore データをコンポーネントにロードする
<p>人物テーブルに名前とプロフィール写真を入力しようとしています。この名前は Firestore データベースから派生し、Firebase バケット内の関連イメージを検索するためにイメージによって使用されます。 </p>
<p>私は何時間ものビデオを見て、ほぼ 100 の記事を読んできました。そのため、サンプル コードには、あらゆる組み合わせを試して組み合わせを試しましたが、成功した結果が得られなかったので、各コードのスニペットが含まれています。 </p>
<p>最小限のエラーを返す現在の状態では、テーブルに名前を正常に入力できますが、同じコンポーネント内でプロフィール写真の抽出に失敗します。プロフィール写真に使用される値が更新されましたが、プレースホルダー値から <code>unknown</code> に更新されました。 </p>
<p><strong>GamePlanner.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><テンプレート>
<div>
<フィールド />
<ベンチ>
<!-- <サスペンス>
<template #default> -->
<計画概要 />
<!-- </template>
<テンプレート #フォールバック>
<div class="loading">読み込み中...</div>
</テンプレート>
</サスペンス> -->
</div>
</テンプレート>
</pre>
<p><strong>Plansummary.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><テンプレート>
<div class="summaryContainer">
<div class="inningTableContainer">
<テーブルクラス="イニングテーブル">
<みんな>
<!-- <サスペンス> -->
<!-- <template #default> -->
<PlayerRow v-for="player.value 内のプレーヤー" :key="プレイヤーID" :player="(プレーヤーとしてのプレーヤー)" />
<!-- </template> -->
<!-- <template #fallback>
<tr data-playerid="0">
<img class="playerImage" src="https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50" />
プレーヤーをロード中...
<span class="playerNumber">00</span>
</tr>
</テンプレート> -->
<!-- </サスペンス> -->
</tbody>
</テーブル>
</div>
</div>
</テンプレート>
<スクリプトセットアップ lang="ts">
import { computed, onErrorCaptured, ref } from "vue";
import { useFirestore, useCollection } from "vuefire";
「firebase/firestore」から { コレクション } をインポートします。
import { Player, Inning } from "@/settings/GamePlanner";
PlayerRow を「./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`)));
// スケジューラのフラッシュ実行中に未処理のエラーが発生しました
// キャッチされません (約束どおり) DOMException: 'Node' で 'insertBefore' の実行に失敗しました: 新しいノードが挿入される前にあるノードは、このノードの子ではありません。
const プレーヤー = ref();
player.value = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// 「関連付けられるアクティブなコンポーネント インスタンスがない場合に onServerPrefetch が呼び出される」という一見無限ループ。
// 5 (??) の未定義のプレイヤーをレンダリングします
// エラーが 1 つ表示されます: Uncaught (in Promise) TypeError: Unknown のプロパティを読み取れません ('substring' を読み取っています)
// const player = computed(() => useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// onErrorCaptured((error, vm, info) => {
// console.log("概要コンポーネントの読み込みエラー: ", error, "vm: ", vm, "info: ", info);
// エラーをスローします。
// });
</スクリプト>
</pre>
<p>
PlayerRow.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><テンプレート>
<tr :key="player2.id" :data-playerid="player2.id">
<td>
<img class="playerImage" :src="playerPictureURL" />
{{ player2.ニックネーム || player2.firstName " 「 player2.lastName }}
<span class="playerNumber">{{ player2.playerNumber }}</span>
</td>
</tr>
</テンプレート>
<script lang="ts"セットアップ>
import { ref, PropType, computed, onMounted, watch } from "vue";
import { useFirebaseStorage, useStorageFileUrl } from "vuefire";
import { ref as storageRef } から 'firebase/storage';
import { Player, Inning } from "@/settings/GamePlanner";
const fs = useFirebaseStorage();
const props =defineProps({
'player': { type: PropType<Player> としてのオブジェクト、必須: true },
// 'イニング': 配列<イニング>
});
const player2 = ref(props.player);
// const イニング = 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}`);
// useStorageFileUrl(playerPictureResource).url.value を文字列として返します。
// });
// 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 を文字列として返します。
// });
const playerPictureURL = ref("https://www.gravatar.com/avatar/205e460b479e2e5b48aec07710c08d50");
非同期関数 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 = 文字列として useStorageFileUrl(playerPictureResource).url.value を待ちます。
}
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);
});
</スクリプト>
</pre>
<p>私の印象は <code><サスペンス></code>
をパッケージ化する必要があります。コンポーネント、私が現在使用しているため <code>storageRef</code>和<コード>useStorageUrl方法、但、但它它似乎似乎了更更问题。。根据文档文档文档并检查代码的定义、它们它们它们它们异步的但是尝试立即
<p><strong>相关软件包版本</strong></p>
<pre class="brush:json;toolbar:false;">{
"vue": "^3.2.45"
"firebase": "^9.15.0",
"タイプスクリプト": "^4.9.3",
"vite": "^4.0.0",
"vue-ルーター": "^4.1.6",
"vue-tsc": "^1.0.11",
「vuefire」: 「3.0.0-beta.6」
}
</pre></p>