I'm making a loader component for when my API calls are loading in. I'd like it to be a container I can place around anything. But I am very new to emits and am not quite sure how to use it in this scenario. What am I doing wrong?
This is my component AppLoader.vue:
<script setup lang="ts">
let loading = ref(false);
const showLoader = () => {
loading.value = !loading;
};
</script>
<template>
<div
v-if="loading"
:class="loading ? 'loading' : ''"
class="loader f-height f-width"
>
LOADER WHOOOOOO
</div>
<slot></slot>
</template>
<style src="./app-loader.css" scoped lang="postcss" />
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;
}
On the page I want to use it:
<AppLoader>Some stuff that takes a while to load....</AppLoader>
And in the script of my page:
<script lang="ts" setup>
const emit= defineEmits(["showLoader"])
onMounted(() => {
emit("showLoader", true); // Show the loader by adding a display:block class
// Fetch all my API calls and process the information on the page
emit("showLoader", false) // Hide the loader by removing the display:block class
});
</script>
Maybe you can try with prop that you send from parent component and watch it in loader:
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>