Vue 3:等待父级完成数据获取以获取子级数据并显示加载器

Tho*_*ore 8 vue.js axios vuex vuejs3

我正在寻找一种可重用的方式来显示完整页面加载器(侧边栏始终可见,但加载器应覆盖页面的内容部分),直到完成所有必要的 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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

我需要的是一种在父组件(LaunchDetails)中获取数据的方法。如果此数据存储在 vuex 存储中,则子组件 ( LaunchRocket) 将获取必要的存储数据并执行获取请求。完成此操作后,我希望在加载父组件时有一个整页加载器或一个整页加载器以及一个包含嵌套画布的加载器。

此时,vuex 存储正在跟踪一个isLoading由 axios 拦截器处理的属性。

所有代码在此沙箱中可见

(注意:在这个例子中,我可以从 url 获取rocket_id,但在我的项目中不会出现这种情况,所以我真的在寻找一种从 vuex 存储获取这些数据的方法)

TEF*_*EFO 4

我介绍一下你的救星Suspense,这个功能已经在 vue v3 中添加了,但仍然是一个实验性功能。基本上它的工作原理是在父组件中创建一个悬念,并且当应用程序任何深度的所有组件都得到解析时,您可以显示加载。请注意,您的组件应该是异步组件,这意味着它应该延迟加载或使您的设置函数(组合 api)成为异步函数,这样它将返回一个异步组件,这样您就可以在子组件和父组件中获取数据如有必要,请显示后备方案。

更多信息: https: //vuejs.org/guide/built-ins/suspense.html#suspense