Vue 3: 상위 항목이 데이터 가져오기가 완료될 때까지 기다렸다가 하위 데이터를 가져오고 로더를 표시합니다.
필요한 API 페치가 모두 완료될 때까지 풀 페이지 로더를 표시할 수 있는 재사용 가능한 방법을 찾고 있습니다(사이드바는 항상 표시되지만 로더는 페이지의 콘텐츠 부분을 커버해야 합니다).
부모 컴포넌트가 있습니다.LaunchDetails에 싸여PageLoader요소
LaunchDetails.vue
<template>
<PageLoader>
<router-link :to="{ name: 'launches' }"> Back to launches </router-link>
<h1>{{ name }}</h1>
<section>
<TabMenu :links="menuLinks" />
</section>
<section>
<router-view />
</section>
</PageLoader>
</template>
<script>
import TabMenu from "@/components/general/TabMenu";
export default {
data() {
return {
menuLinks: [
{ to: { name: "launchOverview" }, display_name: "Overview" },
{ to: { name: "launchRocket" }, display_name: "Rocket" },
],
};
},
components: {
TabMenu,
},
created() {
this.$store.dispatch("launches/fetchLaunch", this.$route.params.launch_id);
},
computed: {
name() {
return this.$store.getters["launches/name"];
},
},
};
</script>
PageLoader.vue
<template>
<Spinner v-if="isLoading" full size="medium" />
<slot v-else></slot>
</template>
<script>
import Spinner from "@/components/general/Spinner.vue";
export default {
components: {
Spinner,
},
computed: {
isLoading() {
return this.$store.getters["loader/isLoading"];
},
},
};
</script>
그LaunchDetails템플릿에 다른 라우터 뷰가 있습니다.이러한 하위 페이지에서는 새로운 가져오기 요청이 의 데이터를 기반으로 작성됩니다.LaunchDetails요청한다.
RocketDetails.vue
<template>
<PageLoader>
<h2>Launch rocket details</h2>
<RocketCard v-if="rocket" :rocket="rocket" />
</PageLoader>
</template>
<script>
import LaunchService from "@/services/LaunchService";
import RocketCard from "@/components/rocket/RocketCard.vue";
export default {
components: {
RocketCard,
},
mounted() {
this.loadRocket();
},
data() {
return {
rocket: null,
};
},
methods: {
async loadRocket() {
const rocket_id = this.$store.getters["launches/getRocketId"];
if (rocket_id) {
const response = await LaunchService.getRocket(rocket_id);
this.rocket = response.data;
}
},
},
};
</script>
필요한 것은 부모 컴포넌트로 데이터를 가져오는 방법입니다(LaunchDetails이 데이터가 vuex 스토어에 저장되어 있는 경우 자 컴포넌트(LaunchRocket)는 필요한 스토어 데이터를 취득하여 fetch 요구를 실행합니다.이 작업을 수행하는 동안 부모 컴포넌트를 로드하는 동안 풀 페이지 로더 또는 풀 페이지 로더를 사용하고 네스트된 캔버스를 포함하는 로더를 원합니다.
이 시점에서 vuex 스토어는 Vuex에 의해isLoading속성, 악시오 가로채기로 처리됩니다.
이 샌드박스에 모든 코드가 표시됨
(주: 이 예에서는, 다음의 정보를 취득할 수 있습니다.rocket_id이 데이터는 vuex 스토어에서 입수할 수 있는 방법을 찾고 있습니다.
당신의 구세주를 소개합니다.Suspense이 기능은 vue v3에서 추가되었지만 아직 시험적인 기능입니다.기본적으로 부모 컴포넌트에 서스펜스를 하나 생성하여 응용 프로그램의 모든 컴포넌트가 해결되었을 때 로드를 표시할 수 있습니다.컴포넌트는 비동기 컴포넌트여야 합니다.즉, 셋업 함수(컴포지션 API)를 느긋하게 로드하거나 비동기 컴포넌트를 반환하도록 하는 것입니다.이렇게 하면 자녀 컴포넌트에서 데이터를 가져오고 필요에 따라 부모 컴포넌트에서 폴백을 표시할 수 있습니다.
상세정보 : https://v3.vuejs.org/guide/migration/suspense.html#introduction
이벤트:
var Child = Vue.component('child', {
data() {
return {
isLoading: true
}
},
template: `<div>
<span v-if="isLoading">Loading …</span>
<span v-else>Child</span>
</div>`,
created() {
this.$parent.$on('loaded', this.setLoaded);
},
methods: {
setLoaded() {
this.isLoading = false
}
}
});
var Parent = Vue.component('parent', {
components: { Child },
data() {
return {
isLoading: true
}
},
template: `<div>
Parent
<Child />
</div>`,
mounted() {
let request1 = new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
});
let request2 = new Promise((resolve, reject) => {
setTimeout(resolve, 2000);
});
Promise.all([ request1, request2 ]).then(() => this.$emit('loaded'))
}
});
new Vue({
components: { Parent },
el: '#app',
template: `<Parent />`
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"></div>
이것은 부모와 자식이 결합되어 이벤트가 반대로 전송되는 것으로 간주되므로 안티 패턴으로 간주될 수 있습니다.이벤트를 사용하지 않으려면 감시하는 자산도 문제 없습니다.부모자녀가 아닌 이벤트 내보내기는 Vue 3에서 삭제되었지만 외부 라이브러리를 사용하여 구현할 수 있습니다.
언급URL : https://stackoverflow.com/questions/70376472/vue-3-wait-until-parent-is-done-with-data-fetching-to-fetch-child-data-and-show
'source' 카테고리의 다른 글
| Nuxt에서는 한 모듈의 Vuex 상태를 다른 모듈에서 변환하려면 어떻게 해야 합니까? (0) | 2022.07.23 |
|---|---|
| Vue Post 함수가 null 본문을 전송합니다. (0) | 2022.07.17 |
| 음, 당신은 PRIU64가 누군가요? (0) | 2022.07.17 |
| Android 부동 동작 버튼 색상 변경 (0) | 2022.07.17 |
| 왜 구조 자체보다는 구조의 첫 번째 요소의 주소를 사용하는가? (0) | 2022.07.17 |