axios Vue 3:等待父项完成数据获取,以获取子项数据并显示加载程序

q5lcpyga  于 2022-11-05  发布在  iOS
关注(0)|答案(2)|浏览(233)

我正在寻找一种可重用的方式来显示一个完整的页面加载器(边栏总是可见的,但加载器应该覆盖页面的内容部分),直到所有必要的api提取已完成。
我有一个封装在PageLoader组件中的父组件LaunchDetails
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)将获取必要的存储数据并执行获取请求。在完成此操作的同时,我希望有一个全页加载器,或者在父组件加载时有一个全页加载器,以及一个包含嵌套画布的加载器。
此时,vuex存储正在跟踪一个isLoading属性,该属性由axios拦截器处理。
所有代码在此sandbox中均可见
(Note:在本例中,我可以从url中获取rocket_id,但在我的项目中却不是这样,因此我正在寻找一种从vuex存储中获取此数据的方法)

s4n0splo

s4n0splo1#

我来介绍你们救世主,这个特性已经被添加到vue v3中,但是仍然是一个实验性的特性。基本上它的工作方式你在父组件中创建一个悬念,当你的应用程序的任何深度的所有组件都被解析时,你可以显示一个加载。注意你的组件应该是一个异步组件,这意味着它应该延迟加载或者使你的设置功能(composition api)一个异步函数,这样它将返回一个异步组件,通过这种方式,你可以在子组件中获取数据,并在必要时在父组件中显示一个回退。
更多信息:https://vuejs.org/guide/built-ins/suspense.html#suspense

tmb3ates

tmb3ates2#

您可以使用事件:
第一个
这可能被认为是一个反模式,因为它将父级与子级耦合,事件被认为是以相反的方式发送的。如果你不想使用事件,监视属性也可以工作。在Vue 3中删除了非父级-子级事件发射,但can be implemented using external libraries

相关问题