What is the best way to trigger the display or concealment of a loader overlay?

I'm currently creating a loader component to display when my API calls are loading. I want this loader to be a versatile container that can be placed around any content. However, my knowledge of emits is limited and I'm unsure of how to properly implement them in this situation. Can you help me identify what I am missing?

Here is the code for my AppLoader.vue component:

<script setup lang="ts">
let isLoading = ref(false);

const toggleLoader = () => {
  isLoading.value = !isLoading;
};
</script>

<template>
  <div
    v-if="isLoading"
    :class="isLoading ? 'loading' : ''"
    class="loader full-height full-width"
  >
    LOADER HERE
  </div>
  <slot></slot>
</template>

<style src="./app-loader.css" scoped lang="postcss" />

And here's the CSS code from app-loader.css:

.loader {
  background: red;
  width: 100%;
  height: 100%;
  position: absolute;
  display: none;
  top: 0;
  left: 0;
  z-index: 10;
  opacity: 0.5;
}

.loading {
    display: block;
}

To utilize the AppLoader component on a page, use the following syntax:

<AppLoader>Content that requires loading time...</AppLoader>

Lastly, in the script section of the page, include the following logic:

<script lang="ts" setup>
const emit = defineEmits(["toggleLoader"])

onMounted(() => {
  emit("toggleLoader", true); // Display the loader by adding a specific class
  // Perform the necessary API calls and data processing
  emit("toggleLoader", false) // Hide the loader by removing the specified class
});
</script>

Answer №1

If you want to try using a prop sent from the parent component and monitor it in the loader, consider the following code:

const { ref, onMounted, watch } = Vue
const app = Vue.createApp({
  setup() {
    const isLoading = ref(true)
    onMounted(() => {
      setTimeout(() => isLoading.value = false, 5000)
    })
    return { isLoading }
  }
})
app.component('loader', {
  template: `
    <div
      v-if="loading"
      :class="loading ? 'loading' : ''"
      class="loader f-height f-width"
    >
      LOADER WHOOOOOO
    </div>
    <slot></slot>
  `,
  props: {
    load: {
      type: Boolean,
      default: true
    }
  },
  setup(props) {
    const loading = ref(props.load);
    watch(
      () => props.load,
      (newValue) => loading.value = newValue
    );
    return { loading }
  }
})
app.mount('#demo')
.loader {
  background: red;
  width: 100%;
  height: 100%;
  position: absolute;
  display: none;
  top: 0;
  left: 0;
  z-index: 10;
  opacity: 0.5;
}
.loading {
  display: block;
}
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <loader :load="isLoading">Some stuff that takes a while to load....</loader>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using class variance authority variants allows for the acceptance of a "null" value, although it is not recommended

My approach with cva is as follows: const checkboxOptions = cva('border ...', { variants: { size: { sm: 'h-4 w-4', md: 'h-5 w-5', lg: 'h-6 w-6', }, }, defaultVariants: ...

Why is the lifecycle callback not being triggered?

I am currently learning how to develop with Vue.js. I have been trying to use the lifecycle callbacks in my code. In my App.vue file, I have implemented the onMounted callback. However, when I run the code, I do not see the message appearing in the consol ...

DataGrid parameters in Material UI are only considering the final value in the table

I am working with a Data Grid table containing user information, and I want to include a sub-menu of options in the last column that opens up a modal for each user. However, I am facing an issue where only the data from the final row in the table is being ...

Using Typescript/JSX to assign a class instance by reference

Looking to access an object's property by reference? See the code snippet below; class Point{ x:number; y:number; constructor(x,y) { this.x=x; this.y=y; } } const a = { first: new Point(8,9), second: new Point(10,12) }; let someBoo ...

The 'state' property is not found on the 'FetchPeriod' type

Currently, I am embarking on a journey to grasp ReactJS by following a tutorial provided at this Tutorial. Being a novice in the programming language, I find myself at a loss as to what steps to take next. One roadblock I encountered was when attempting ...

Utilizing the MapToIterable Angular Pipe with TypeScript

Exploring the implementation of a pipe in Angular. Discovered that ngFor doesn't work with maps, prompting further research to find a solution. It seems that future features may address this issue, but for now, utilizing a mapToIterable pipe is the re ...

What is the best way to indicate a particular element within a subdocument array has been altered in mongoose?

I have a specific structure in my Mongoose schema, shown as follows: let ChildSchema = new Schema({ name:String }); ChildSchema.pre('save', function(next){ if(this.isNew) /*this part works correctly upon creation*/; if(this.isModifi ...

Retrieve the overall number of job openings from the Github Job API

I have successfully created an Angular application that mirrors the functionality of However, I encountered a limitation where only 50 positions are available per page, To fetch additional jobs beyond the initial 50, I need to append "?page=X" to another ...

Create a TypeScript arrow function and set it as the return value

Looking to create a TypeScript Declaration for ReactMeteorData.jsx, which consists of the following exporting functionality: export default function connect(options) { let expandedOptions = options; if (typeof options === 'function') { e ...

Error in Webpack: "Module cannot be found: unable to resolve in tsx files"

Attempting to deploy my React projects to the development server has been successful on my local Macbook. However, issues arose when deploying the React project to PM2 in the development server. Here are some excerpts from the error messages: 2021-01-20 1 ...

How can you extract the contents of a div tag that includes an image tag using regular expressions in JavaScript?

I have a string that was generated with the following content tesgddedd<br> <div><img style="max-width: 10rem;" src="folder/mypicture.jpg"><div> <br></div></div> My goal is to target the div co ...

Using TypeScript's Non-Null Assertion Operators in combination with square brackets []

One way to assert that an object has a certain property is by using the `!.` syntax as shown below: type Person = { name: string; age: number; gender?: string; } const myPerson: Person = { name: 'John Cena', age: 123, gender: 's ...

Implementing a night mode switch in a Vuetify application version 2.0 built on Nuxt.js

I have integrated the nuxt.js vuetify template, and within the nuxt.config.js file, there is an object (shown below) that sets up the dark mode for the application. vuetify: { customVariables: ['~/assets/variables.scss'], theme: { ...

Tips on creating a unit test for validating errors with checkboxes in your code base

In a certain scenario, I need to display an error message when a user clicks on the Next button without agreeing to the terms. To achieve this, I am looking to write a unit test case using Jest and React Testing Library. How can I go about doing this? im ...

Strategies for transferring data from index.html to component.ts in Angular 4

Greetings, as a newcomer to Angular, I am seeking advice on how to link my Index.html file to component.ts. Please review the code snippet below where I have created a function called scannerOutput in my Angular index.html file which is functioning properl ...

Stream and upload videos, images, documents, and more all with the power of Laravel VueJs

I have successfully uploaded a video, but I am having trouble streaming it from the Laravel storage/app folder. Here is my Vue Js code: <video width="120" height="240" controls> <source :src="videoFullPath" type=& ...

Steps to display all Vue files in test coverage using Vue-cli 3 and Jest

I'm hitting a snag while attempting to set up Vue CLI 3 with Jest for displaying test coverage. Despite my best efforts, the coverage report still shows zero coverage: Ran all test suites. ----------|----------|----------|----------|----------|------ ...

Converting strict primitive types to primitive types in Typescript

I have a function that parses a string into a value and returns a default value if it fails. The issue is that this code returns too strict types for primitives, such as `false` instead of `boolean`. How can I resolve this? Should I utilize some form of ...

React with TypeScript: The children prop of this JSX tag is specifically looking for a single child of type ReactNode, but it seems that multiple children were passed instead

For my class project in APIs, I am using react-typescript but running into issues. My problem arises when attempting to loop through an array of "popular" movies using .map. However, I keep getting this error message: "This JSX tag's 'children&ap ...

VueJs - Add a button following a v-select element

I am relatively new to using Bootstrap-Vue for a project, and I have a structure set up in this way <template> <v-select> <template slot="option" slot-scope="option"> <div class="d-center"> ...