I'm looking for a reusable way to display a full page loader (Sidebar always visible but the loader should cover the content part of the page) till all necessary api fetches has been done.
I've got a parent component LaunchDetails wrapped in a PageLoader component
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>
The LaunchDetails template has another router-view. In these child pages new fetch requests are made based on data from the LaunchDetails requests.
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>
What I need is a way to fetch data in the parent component (LaunchDetails). If this data is stored in the vuex store, the child component (LaunchRocket) is getting the necessary store data and executes the fetch requests. While this is done I would like to have a full page loader or a full page loader while the parent component is loading and a loader containing the nested canvas.
At this point the vuex store is keeping track of an isLoading property, handled with axios interceptors.
All code is visible in this sandbox
(Note: In this example I could get the rocket_id from the url but this will not be the case in my project so I'm really looking for a way to get this data from the vuex store)