source

Vue 3: 상위 항목이 데이터 가져오기가 완료될 때까지 기다렸다가 하위 데이터를 가져오고 로더를 표시합니다.

goodcode 2022. 7. 17. 00:27
반응형

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 &hellip;</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

반응형