Adjust the internal state within a Vue3 component using a window function

Creating a "Loader" component that is fully independent and functional just by being included in the layout requires exposing some methods for use. Here is the code I have come up with:

<script setup>
let active = false;

function show() {
    active = true;
}

function hide() {
    active = false;
}

window.loader = {show, hide};
</script>


<template>
    <Transition name="loader">
        <div class="loader" v-if="active">
        </div>
    </Transition>
</template>

<style scoped>
/* All styles and transitions */
.loader {
    position: fixed;
    height: 100vh;
    width: 100vw;
    background: #000;
    z-index: 9999;
    top: 0;
    left: 0;
    opacity: 0.5;
}
</style>

However, the show and hide methods do not update the internal state of the component as intended.

The goal is to include it in BaseLayout.vue like this:

<template>
  <div class="root">
    <Loader />

    <slot>All application body</slot>
  </div>
</template>

Is there a way to globally expose these functions and effectively change the internal state of the loader component? Are there any patterns or solutions to address this issue efficiently, considering its usage across multiple layouts?

Answer №1

To achieve this functionality, you can implement the following code:

<script setup>
import {ref} from 'vue'

let active = ref(false);

function displayLoader() {
    active.value = true;
}

function hideLoader() {
    active.value = false;
}

window.loader = {displayLoader, hideLoader, active};
</script>


<template>
    <Transition name="loader">
        <div class="loader" v-if="active">
        </div>
    </Transition>
</template>

<style scoped>
/* Styling and transitions for the loader */
.loader {
    position: fixed;
    height: 100vh;
    width: 100vw;
    background: #000;
    z-index: 9999;
    top: 0;
    left: 0;
    opacity: 0.5;
}
</style>

This implementation ensures that Vue detects changes accurately.

Answer №2

To create a composable function that can be accessed globally, define a function with a ref property outside the function and use its methods to change its state:

File: useLoader.js

import {ref} from 'vue';
const active = ref(false);

export default function useLoader() {
  function show() {
    active.value = true;
  }

  function hide() {
      active.value = false;
 }


return {active,hide,show}
}

In the loader component:

<script setup>
import useLoader from './useLoader'

const {active} =useLoader();
</script>


<template>
    <Transition name="loader">
        <div class="loader" v-if="active">
        </div>
    </Transition>
</template>

In another component:

<script setup>
import useLoader from './useLoader'

const {show,hide} =useLoader();
</script>
<template>
  <div class="root">
   <button @click="show">Show Loader</button>
    <Loader />

    <slot>All application body</slot>
  </div>
</template>

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

A captivating opportunity for a web developer specializing in frontend design

Encountered an intriguing dilemma that has me stumped. There is a single stipulation: Only the json can be altered! I am struggling to meet this requirement: data.hasOwnProperty("\u{0030}") class JobHunter { get data() { return &ap ...

The antithesis of a feature that encapsulates a chosen area with a span

Hi everyone, I have a function that works as follows: define(function () { 'use strict'; var sel, range, span; return function () { span = document.createElement("span"); span.className = 'highlight'; if (window.ge ...

Using type annotations is restricted to TypeScript files only, as indicated by error code ts(8010)

I encountered an issue with React.MouseEvent<HTMLElement> const handleOpenNavMenu = (event: React.MouseEvent<HTMLElement>) => { setAnchorElNav(event.currentTarget); }; const handleOpenUserMenu = (event: React.MouseEvent<HTMLElement ...

What is the most effective approach for delivering arguments to event handlers?

Consider the following block of HTML: <button id="follow-user1" class="btnFollow">Follow User1</button> <button id="follow-user2" class="btnFollow">Follow User2</button> <button id="follow-user3" class="btnFollow">Follow User ...

Navigating router queries within Nuxt: A step-by-step guide

One of the challenges I am facing is passing value parameters in my URL with the mounted function looking like this: mounted () { this.$router.push({ path: '/activatewithphone', query: { serial: this.$route.params.serial, machin ...

Grid items in Material UI are not positioned next to each other

I am encountering an issue with the Grid component in material-ui. The grid items are currently stacking below each other instead of beside each other, and I'm unsure of what is causing this behavior. My intention is for the grid items to stack on top ...

What are the steps to apply an AngularJS filter for formatting values within an array?

While I have experience using angular filters for formatting primitive values like numbers into currency formats, I am now faced with the challenge of applying the same filtering to an array of values. For example: price = 1 prices = [1,2,3] If I were to ...

Utilize Javascript/Jquery to categorize JSON data based on the days of the week (Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)

A function is provided below that retrieves data for a chart. The output produced by this function is structured as follows: [Object { date=Date, value=112, volume=1469}, Object { date=Date, value=124, volume=539}, Object { date=Date, value=114, vo ...

Adjust the hue of the X axis labels to display a variety of colors within Chart.js

Utilizing Chart.js for my bar chart. The X axis labels contain 4 lines, and I want to change the color of each line individually rather than having all values in one color. var barChartData = { labels: [["Injection", 10, 20], // Change the color here ...

The fuse-sidebar elements are not being properly highlighted by Introjs

I have recently developed an angular project that utilizes the fuse-sidebar component. Additionally, I am incorporating introjs into the project. While introjs is functioning properly, it does not highlight elements contained within the fuse-sidebar. The ...

What is the purpose of using @ViewChild to access a component's function from another component?

During a discussion with my tutor, I learned that in Angular we can utilize functions defined in any service by simply importing the service. However, unlike services, components cannot be directly imported into other components. To access a function from ...

What is V8's approach to managing dictionaries?

After attending V8 presentations, it became clear to me that it optimizes constructions such as the one below by tagging a type object: function Point(x, y) { this.x = x; this.y = y; } I am curious about what happens if I were to return an object (JS ...

Challenge with Transferring Data to be Displayed

My issue lies in calling a function with 3 inputs - 2 numbers and 1 string. The two numbers are being passed correctly, but I need the string to be printed within the element. I suspect the problem is related to passing the parameter to an HTML part of th ...

How can data be shared between two functional child components in a React application?

I've been researching on Google quite a bit on how to transfer props between functional components, but it seems like there isn't much information available (or maybe I'm not using the right keywords). I don't need Redux or globally st ...

Oops! Looks like there's an issue with the rendering function or template in this component - it

After following the instructions in the tutorial at , I attempted to implement the example but encountered an issue that seems to be missing from the guide. const Vue = require('vue'); const server = require('express')(); const vssr = ...

Understanding the moment when the DOM is fully rendered within a controller

I'm currently facing an issue with AngularJS. In my controller, I have a $watch setup like this: function MyController() { $watch('myModel', function() { $rootScope.$emit('do-oper'); }); } The value of 'myMod ...

Is there a way to automatically redirect the main html page to a different html page upon logging in?

I have created a main page in HTML with a login box that displays a message saying "Login successful" or "Login failed" based on whether the password entered is 8 characters or more. The validation function for this works correctly, but after successfully ...

How does the question mark symbol (?) behave when utilizing it in response? Specifically in relation to data, the API, and the fetch API

Have you encountered the curious sequence of symbols in this context? data?.name Could you explain the significance of the question mark (?) between 'data' and the period? ...

Explore RxJs DistinctUntilChanged for Deep Object Comparison

I have a scenario where I need to avoid redundant computations if the subscription emits the same object. this.stateObject$ .pipe(distinctUntilChanged((obj1, obj2) => JSON.stringify({ obj: obj1 }) === JSON.stringify({ obj: obj2 }))) .subscribe(obj =& ...

The jQuery Select2 Plugin for Dynamic Dropdowns with Ajax Integration

Utilizing the Select2 plugin with Ajax to connect to my employee database has been quite helpful. It allows setting up a meeting and selecting all the employees you wish to invite. Here is an example of the code: $("#requiredAttendees").select2({ ...