2👍
so thanks to Neha Soni’s answer, I found out about
Pinia
and what I had in mind, looks like the following:
I installed pinia, created a store
folder under src
, and created there an isloading.ts
file, which looks like this:
import { defineStore } from "pinia";
import { reactive, ref } from "vue";
export const useLoaderState = defineStore("isLoading", () => {
const state = ref(false)
const changeStateTrue = () => {
state.value = true
}
const changeStateFalse = () => {
state.value = false
}
return { state, changeStateTrue, changeStateFalse }
})
In router/index.ts
, I have the following logic that awaits for a bit before actually rendering the clicked route, and saves to the global variable isLoading as state a boolean:
router.beforeEach((to, from, next) => {
const isLoading = useLoaderState();
const { changeStateTrue } = isLoading;
console.log("beforeach");
changeStateTrue();
console.log(isLoading.state);
setTimeout(() => {
next();
}, 500);
});
router.afterEach((to, from) => {
const isLoading = useLoaderState();
const { changeStateFalse } = isLoading;
console.log("aftereach");
changeStateFalse();
console.log(isLoading.state);
});
Finally, in my App.vue
I have the following for my PreLoader, which is just for a loading screen:
<script setup lang="ts">
import { useLoaderState } from "./store/isloading";
const isLoading = useLoaderState();
</script>
<template>
<PreLoader v-if="isLoading.state" :class="[currentTheme]" />
</template>
I wanted even my loader to change according to the already applied dark/light mode, so thats what the :class="[currentTheme]"
is there for, what is important is the v-if="isLoading.state"
, which first gets into this component with calling the Pinia way the isLoading
global variable with
- importing the defined store with
import { useLoaderState } from "./store/isloading";
- creating a constant in this current
App.vue
with theconst isLoading = useLoaderState();
From there, the constant’s values and states (including the boolean which I wanted) lives reactively in this current component (in this case, the App.vue
), and the v-if
will get updated therefore dynamically.
1👍
The following two approaches can help you-
1. Using event bus-
- Emit an event on the router’s before and after hook and pass a status true/false.
router.beforeEach((to, from, next) =>{
eventbus.emit('loader-status', true)
});
router.afterEach((to, from) => {
eventbus.emit('loader-status', true)
});
- Listen to this event in your loader component and show/hide the loader as per the status passed by the event.
eventbus.on('loader-status', status => { this.showLoader = status })
Here you can read- How to use event buses in vue3.
2. Using Vuex-
- Create a variable named
showLoader
in the Vuex state. - Update that variable on routers before and after the hook.
router.beforeEach((to, from, next) =>{
// call a mutation to update the showLoader to true
});
router.afterEach((to, from) => {
// call a mutation to update the showLoader to false
});
- Use this global variable’s value in the Loader component to show/hide the loader.
<Loader v-if="store.state.showLoader"></Loader>
Here you can read- How to set up Vuex in vue3.
NOTE-
I only provided the logical code, syntax would be different when you use any of the above approaches.
- [Vuejs]-How do I update translated text when changing a language in a Vue.js app with i18n and Pinia?
- [Vuejs]-Nuxt 3 (Vue.js 3) component transitions not working