Home > Enterprise >  Change local state from window function in Vue3
Change local state from window function in Vue3

Time:10-18

I want to make a "Loader" component, I want it to be fully independent and already working just by being included in the layout. but to be able to use it I need to expose some methods

So I arrived at the following code:

<script setup>
let active = false;

function show() {
    active = true;
}

function hide() {
    active = false;
}

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


<template>
    <Transition name="loader">
        <div  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 change the internal state of the component

I want to use it like this: BaseLayout.vue

<template>
  <div >
    <Loader />

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

Is there any way to expose these functions globally and change the internal state of the loader component?

Is there a pattern I can use to solve this problem?

I use this loader in several different layouts and I would like to use as little code as possible to insert in a new layout

CodePudding user response:

You can do something like :

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

let active = ref(false);

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

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

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


<template>
    <Transition name="loader">
        <div  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>

it will allow vue to detect changes correctly

CodePudding user response:

Define a composable function with ref property outside the function in order to be global, and use that methods to change its state :

useLoader.js

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

export default 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  v-if="active">
        </div>
    </Transition>
</template>

in other component :

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

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

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