>  Q&A  >  본문

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" }

P粉790187507P粉790187507416일 전573

모든 응답(1)나는 대답할 것이다

  • P粉432906880

    P粉4329068802023-08-30 11:59:52

    문서 에 따르면 useCollection 包含 collection를 다음과 같은 매개변수로 사용해야 합니다.

    으아악

    올바른 방법으로 사용하고 계신 것으로 보입니다만, players 变量,而不是分配给 ref 。当您尝试使用此反应式对象作为 ref객체의 값에 직접 할당할 수 있는데 이는 지원되지 않습니다.

    다음 줄을 변경하면 문제를 해결할 수 있습니다.

    으아악

    받는 사람:

    으아악

    이 주제에 대한 자세한 내용을 보려면 다음 문서

    를 찾아보세요.

    회신하다
    0
  • 취소회신하다