Step 1: Building the Overlay Component
Create a component named DynamicOverlay.vue. This component accepts a media source property and manages its own visibility, including a automatic shutdown mechanism if the process takess too long.
<template>
<view v-show="isVisible" class="overlay-container">
<image class="media-source" :src="mediaUrl" mode="aspectFit"></image>
<text class="status-text">Please wait...</text>
</view>
</template>
<script>
export default {
name: 'DynamicOverlay',
props: {
mediaUrl: {
type: String,
default: ''
}
},
data() {
return {
isVisible: true
};
},
mounted() {
// Safety switch: Force hide the overlay after 10 seconds
setTimeout(() => {
this.isVisible = false;
this.$emit('timeout');
}, 10000);
}
};
</script>
<style scoped>
.overlay-container {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: rgba(255, 255, 255, 0.9);
z-index: 10000;
}
.media-source {
width: 300rpx;
height: 300rpx;
}
.status-text {
margin-top: 20rpx;
font-size: 28rpx;
color: #333;
}
</style>
Step 2: Global Registration
Register the component in main.js so it becomes available throughout the application without needing local imports in every page.
import DynamicOverlay from '@/components/overlay/DynamicOverlay.vue';
// Register as a global component
Vue.component('DynamicOverlay', DynamicOverlay);
Step 3: Prepare Media Assets
Place your animation files (such as .gif, .mp4, or static images) inside the static directory. For example, save them in static/animations/.
Step 4: Integration in a Page
Use the component in your view layer. Control the visibility via a data property and hide the overlay once your asynchronous logic (like an API call) completes.
<template>
<view class="page-container">
<DynamicOverlay
v-if="loadingActive"
:media-url="animationPath"
@timeout="handleLoadTimeout"
/>
<view v-else class="content-area">
<!-- Main content displayed after loading -->
</view>
</view>
</template>
<script>
export default {
data() {
return {
loadingActive: true,
animationPath: '/static/animations/loader.mp4'
};
},
methods: {
handleLoadTimeout() {
console.warn('Loading timed out after 10 seconds.');
this.loadingActive = false;
}
},
mounted() {
// Simulate an API request or data processing
const mockFetch = setTimeout(() => {
this.loadingActive = false;
}, 2500);
// Clear timeout if component is destroyed early
this.$once('hook:beforeDestroy', () => clearTimeout(mockFetch));
}
};
</script>
<style scoped>
.page-container {
padding: 20rpx;
}
</style>