1<template> 2 <transition name="fade"> 3 <b-progress v-if="!isLoadingComplete"> 4 <b-progress-bar 5 striped 6 animated 7 :value="loadingIndicatorValue" 8 :aria-label="$t('global.ariaLabel.progressBar')" 9 /> 10 </b-progress> 11 </transition> 12</template> 13 14<script> 15import { useI18n } from 'vue-i18n'; 16export default { 17 data() { 18 return { 19 $t: useI18n().t, 20 loadingIndicatorValue: 0, 21 isLoadingComplete: false, 22 loadingIntervalId: null, 23 timeoutId: null, 24 }; 25 }, 26 created() { 27 this.$eventBus.on('loader-start', () => { 28 this.startLoadingInterval(); 29 }); 30 this.$eventBus.on('loader-end', () => { 31 this.endLoadingInterval(); 32 }); 33 this.$eventBus.on('loader-hide', () => { 34 this.hideLoadingBar(); 35 }); 36 }, 37 beforeUnmount() { 38 this.$eventBus.off('loader-start', this.handleLoaderStart); 39 this.$eventBus.off('loader-end', this.handleLoaderEnd); 40 this.$eventBus.off('loader-hide', this.handleLoaderHide); 41 }, 42 methods: { 43 startLoadingInterval() { 44 this.clearLoadingInterval(); 45 this.clearTimeout(); 46 this.loadingIndicatorValue = 0; 47 this.isLoadingComplete = false; 48 this.loadingIntervalId = setInterval(() => { 49 this.loadingIndicatorValue += 1; 50 if (this.loadingIndicatorValue > 100) this.clearLoadingInterval(); 51 }, 100); 52 }, 53 endLoadingInterval() { 54 this.clearLoadingInterval(); 55 this.clearTimeout(); 56 this.loadingIndicatorValue = 100; 57 this.timeoutId = setTimeout(() => { 58 // Let animation complete before hiding 59 // the loading bar 60 this.isLoadingComplete = true; 61 }, 1000); 62 }, 63 hideLoadingBar() { 64 this.clearLoadingInterval(); 65 this.clearTimeout(); 66 this.loadingIndicatorValue = 0; 67 this.isLoadingComplete = true; 68 }, 69 clearLoadingInterval() { 70 if (this.loadingIntervalId) clearInterval(this.loadingIntervalId); 71 this.loadingIntervalId = null; 72 }, 73 clearTimeout() { 74 if (this.timeoutId) clearTimeout(this.timeoutId); 75 this.timeoutId = null; 76 }, 77 }, 78}; 79</script> 80 81<style lang="scss" scoped> 82.progress { 83 position: absolute; 84 left: 0; 85 right: 0; 86 bottom: -0.4rem; 87 opacity: 1; 88 transition: opacity $duration--moderate-01 $standard-easing--productive; 89 height: 0.4rem; 90 91 &.fade-enter, // Remove this vue2 based only class when switching to vue3 92 &.fade-enter-from, // This is vue3 based only class modified from 'fade-enter' 93 &.fade-leave-to { 94 opacity: 0; 95 } 96} 97.progress-bar { 98 background-color: $loading-color; 99} 100</style> 101