Vuefire로 렌더링하기 전에 구성요소에 Firestore 데이터 로드
<p>이름과 프로필 사진으로 인물 테이블을 채우려고 합니다. 이름은 Firestore 데이터베이스에서 파생되며 이미지가 Firebase 버킷에서 관련 이미지를 찾는 데 사용됩니다. </p>
<p>저는 몇 시간 동안 비디오를 시청했고 거의 100개의 기사를 읽었으므로 모든 조합을 시도하고 조합을 얻었지만 성공적인 결과를 얻지 못했기 때문에 예제 코드에는 각 코드의 스니펫이 포함되어 있습니다. </p>
<p>최소한의 오류를 반환하는 현재 상태에서는 테이블에 이름을 성공적으로 채울 수 있지만 동일한 구성 요소 내에서는 프로필 사진을 추출하지 못합니다. 프로필 사진에 사용된 값이 업데이트되었지만 자리표시자 값에서 <code>undefound</code>로 업데이트되었습니다. </p>
<p><strong>GamePlanner.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><템플릿>
<div>
<필드 />
<벤치 />
<!-- <서스펜스>
<템플릿 #기본>
<계획요약 />
<!-- </템플릿>
<템플릿 #fallback>
<div class="loading">로드 중...</div>
</템플릿>
</서스펜스>
</div>
</템플릿>
</pre>
<p><strong>PlanSummary.vue</strong></p>
<pre class="brush:vue;toolbar:false;"><템플릿>
<div class="summaryContainer">
<div class="inningTableContainer">
<테이블 클래스="inningTable">
<본문>
<!-- <서스펜스> -->
<!-- <템플릿 #기본값> -->
<PlayerRow v-for="players.value" :key="player.id" :player="(플레이어로서의 플레이어)" />
<!-- </템플릿> -->
<!-- <템플릿 #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">
"vue"에서 import { 계산, onErrorCaptured, ref };
"vuefire"에서 import { useFirestore, useCollection };;
"firebase/firestore"에서 { 컬렉션 } 가져오기;
"@/definitions/GamePlanner"에서 { Player, Inning } 가져오기;;
"./PlayerRow.vue"에서 PlayerRow를 가져옵니다.
const db = useFirestore();
const gamePlanID = "O278vlB9Xx39vkZvIsdP";;
// const 플레이어 = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// const 플레이어 = ref(useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// 스케줄러 플러시 실행 중 처리되지 않은 오류
// Uncaught (in promise) DOMException: 'Node'에서 'insertBefore'를 실행하지 못했습니다. 새 노드가 삽입되기 전의 노드는 이 노드의 하위 노드가 아닙니다.
const 플레이어 = ref();
플레이어.값 = useCollection(collection(db, `/gameplans/${gamePlanID}/participants`));
// "연결할 활성 구성 요소 인스턴스가 없을 때 onServerPrefetch가 호출됩니다."를 사용하는 무한 루프처럼 보입니다.
// 정의되지 않은 플레이어 5명(??)을 렌더링합니다.
// 표시된 오류 하나: Uncaught(약속 있음) TypeError: 정의되지 않은 속성을 읽을 수 없습니다('하위 문자열' 읽기).
// const 플레이어 = 계산(() => useCollection(collection(db, `/gameplans/${gamePlanID}/participants`)));
// onErrorCaptured((error, vm, info) => {
// console.log("요약 구성요소 로드 중 오류 발생: ", error, "vm: ", vm, "info: ", info);
// 오류 발생;
// });
</스크립트>
</pre>
<p><strong>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>
</템플릿>
<스크립트 lang="ts" 설정>
"vue"에서 import { ref, PropType, 계산, onMounted, watch };
"vuefire"에서 import { useFirebaseStorage, useStorageFileUrl }를;;
'firebase/storage'에서 { ref as StorageRef } 가져오기;
"@/definitions/GamePlanner"에서 { Player, Inning } 가져오기;;
const fs = useFirebaseStorage();
const 소품 = 정의Props({
'player': { 유형: PropType<Player>로서의 개체, 필수: true },
// '이닝': 배열<이닝>
});
const player2 = ref(props.player);
// const 이닝 = 계산(() =>props.innings);
// const playerPictureURL = 계산(() => {
// 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 = wait 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><PlayerRow></code> 组件,因为我政使用 <code>storageRef</code> 와 < code>useStorageUrl 방법, 但它似乎引入了更多问题.根据 vuefire 文档并检查代码本身的定义,它们似乎并不是异步的,但步尝试立即调用它们不会产生立即/实际结果。</p>
<p><strong>件包版本</strong></p>
<pre class="brush:json;toolbar:false;">{
"vue": "^3.2.45"
"firebase": "^9.15.0",
"타입스크립트": "^4.9.3",
"초대": "^4.0.0",
"vue-router": "^4.1.6",
"vue-tsc": "^1.0.11",
"vuefire": "3.0.0-beta.6"
}