vue实现loading页面
实现全局Loading组件
在components文件夹下创建Loading.vue文件:
<template>
<div v-if="isLoading" class="loading-overlay">
<div class="spinner"></div>
</div>
</template>
<script>
export default {
data() {
return {
isLoading: false
}
},
methods: {
show() {
this.isLoading = true
},
hide() {
this.isLoading = false
}
}
}
</script>
<style>
.loading-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
justify-content: center;
align-items: center;
z-index: 9999;
}
.spinner {
width: 50px;
height: 50px;
border: 5px solid #f3f3f3;
border-top: 5px solid #3498db;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
注册全局Loading
在main.js中注册为全局组件:

import Vue from 'vue'
import App from './App.vue'
import Loading from './components/Loading.vue'
Vue.component('Loading', Loading)
const loading = new Vue(Loading).$mount()
document.body.appendChild(loading.$el)
Vue.prototype.$loading = {
show: () => loading.show(),
hide: () => loading.hide()
}
new Vue({
render: h => h(App)
}).$mount('#app')
在请求拦截器中使用
在axios拦截器中控制Loading显示:
import axios from 'axios'
axios.interceptors.request.use(config => {
Vue.prototype.$loading.show()
return config
}, error => {
Vue.prototype.$loading.hide()
return Promise.reject(error)
})
axios.interceptors.response.use(response => {
Vue.prototype.$loading.hide()
return response
}, error => {
Vue.prototype.$loading.hide()
return Promise.reject(error)
})
按需使用的示例
在组件中手动控制Loading:

export default {
methods: {
fetchData() {
this.$loading.show()
axios.get('/api/data')
.then(response => {
// 处理数据
})
.finally(() => {
this.$loading.hide()
})
}
}
}
路由切换时的Loading
在路由配置中添加导航守卫:
import Router from 'vue-router'
const router = new Router({
routes: [...]
})
router.beforeEach((to, from, next) => {
Vue.prototype.$loading.show()
next()
})
router.afterEach(() => {
setTimeout(() => {
Vue.prototype.$loading.hide()
}, 300)
})
export default router
优化加载体验
添加最小显示时间避免闪烁:
let minLoadingTime = 500
let startTime = 0
Vue.prototype.$loading = {
show: () => {
startTime = Date.now()
loading.show()
},
hide: () => {
const elapsed = Date.now() - startTime
const remaining = minLoadingTime - elapsed
if (remaining > 0) {
setTimeout(() => loading.hide(), remaining)
} else {
loading.hide()
}
}
}






