Overlay Loading Management

User
we have overlay component add in common layout and run from any view where

loading is true

Assistant
If you have an `OverlayLoading` component inside a common layout and it runs whenever `loading` is `true`, but you need to control it from any view, you have a few ways to manage it globally in your Vue 3 application.

### **Solution Approaches:**

#### **1. Using Vue's Global State Management (Pinia or Vuex)**
Since you're using Vue 3, **Pinia** is recommended for state management.

##### **Steps to Implement:**
1. Install Pinia (if not already installed):

yarn add pinia

2. Create a Pinia store (`store/loading.js`):

import { defineStore } from "pinia";

   export const useLoadingStore = defineStore("loading", {
     state: () => ({
       loading: false,
     }),
     actions: {
       setLoading(value) {
         this.loading = value;
       },
     },
   });

3. Update your `OverlayLoading` usage in the common layout:

<script setup>
   import { useLoadingStore } from "@/store/loading";

   const loadingStore = useLoadingStore();
   </script>

   <template>
     <OverlayLoading :overlay="loadingStore.loading" />
   </template>

4. In any view where you need to show/hide the overlay, update the state:

<script setup>
   import { useLoadingStore } from "@/store/loading";

   const loadingStore = useLoadingStore();

   function fetchData() {
     loadingStore.setLoading(true);
     setTimeout(() => {
       loadingStore.setLoading(false);
     }, 2000);
   }
   </script>

   <template>
     <button @click="fetchData">Fetch Data</button>
   </template>

#### **2. Using Provide/Inject (For Simpler Apps)**
If you don’t want to use Pinia, you can pass the `loading` state via Vue’s `provide/inject`.

##### **In Your Common Layout (`App.vue` or `Layout.vue`):**

<script setup>
import { ref, provide } from "vue";

const loading = ref(false);

provide("loading", loading);
</script>

<template>
  <OverlayLoading :overlay="loading" />
  <slot />
</template>

##### **In Any Child Component or View (`Home.vue`, `Dashboard.vue`, etc.):**

<script setup>
import { inject } from "vue";

const loading = inject("loading");

function fetchData() {
  loading.value = true;
  setTimeout(() => {
    loading.value = false;
  }, 2000);
}
</script>

<template>
  <button @click="fetchData">Fetch Data</button>
</template>

#### **Which Approach to Choose?**
– **Use Pinia** ✅ if you need **global state management** and might use the loading indicator in multiple places.
– **Use Provide/Inject** ✅ if it's a **small app** and you don’t want extra dependencies.

Let me know if you need further refinements! 🚀

Leave a Comment

Your email address will not be published. Required fields are marked *