primevue-mirror/components/demo/DeferredDemo.vue

56 lines
1.2 KiB
Vue

<template>
<div v-if="!visible" class="demo-section-loading">Loading...</div>
<slot v-else></slot>
</template>
<script>
export default {
name: 'DeferredDemo',
emits: ['load'],
props: {
options: {
type: Object,
default: null
}
},
data() {
return {
visible: false
};
},
observer: null,
timeout: null,
mounted() {
this.observer = new IntersectionObserver(([entry]) => {
clearTimeout(this.timeout);
if (entry.isIntersecting) {
this.timeout = setTimeout(() => {
this.visible = true;
this.observer.unobserve(this.$el);
this.$emit('load');
}, 350);
}
}, this.options);
this.observer.observe(this.$el);
},
beforeUnmount() {
!this.visible && this.$el && this.observer?.unobserve(this.$el);
clearTimeout(this.timeout);
}
};
</script>
<style>
.demo-section-loading {
display: grid;
place-items: center;
padding: 2rem;
border-radius: 10px;
margin-bottom: 1rem;
font-size: 2rem;
height: 350px;
background: var(--maskbg);
}
</style>