vue 怎么实现loading
实现全局 Loading 的方法
在 Vue 中可以通过封装一个全局组件配合 Vuex 或 Pinia 状态管理实现。创建一个 Loading.vue 组件,通过 v-if 控制显示隐藏:
<template>
<div v-if="isLoading" class="loading-overlay">
<div class="spinner"></div>
</div>
</template>
<script>
export default {
computed: {
isLoading() {
return this.$store.state.isLoading
}
}
}
</script>
在 Vuex 中定义状态并提交 mutation 控制:
const store = new Vuex.Store({
state: {
isLoading: false
},
mutations: {
setLoading(state, status) {
state.isLoading = status
}
}
})
指令式 Loading 的实现
通过 Vue 指令可以在任意元素上触发 Loading 状态。注册一个 v-loading 指令:
Vue.directive('loading', {
bind(el, binding) {
const loadingDiv = document.createElement('div')
loadingDiv.className = 'loading-mask'
el.loadingElement = loadingDiv
if (binding.value) {
el.appendChild(loadingDiv)
}
},
update(el, binding) {
if (binding.value !== binding.oldValue) {
if (binding.value) {
el.appendChild(el.loadingElement)
} else {
el.removeChild(el.loadingElement)
}
}
}
})
请求拦截器集成
在 axios 拦截器中自动管理 Loading 状态:
axios.interceptors.request.use(config => {
store.commit('setLoading', true)
return config
})
axios.interceptors.response.use(
response => {
store.commit('setLoading', false)
return response
},
error => {
store.commit('setLoading', false)
return Promise.reject(error)
}
)
组件级 Loading 控制
在单个组件内部管理 Loading 状态:
<template>
<button @click="fetchData" :disabled="isLoading">
{{ isLoading ? 'Loading...' : 'Submit' }}
</button>
</template>
<script>
export default {
data() {
return {
isLoading: false
}
},
methods: {
async fetchData() {
this.isLoading = true
try {
await axios.get('/api/data')
} finally {
this.isLoading = false
}
}
}
}
</script>
第三方库的使用
常用 Loading 库如 element-ui 提供现成方案:
import { Loading } from 'element-ui'
let loadingInstance = Loading.service({
fullscreen: true,
text: '加载中'
})
// 关闭加载
loadingInstance.close()
对于 Vue 3 项目,可以使用 vue-loading-overlay:
import Loading from 'vue-loading-overlay'
import 'vue-loading-overlay/dist/vue-loading.css'
app.component('Loading', Loading)
动画效果优化
为 Loading 添加 CSS 动画提升用户体验:
.loading-spinner {
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
按需加载配置
通过动态导入实现 Loading 组件的按需加载:

const LoadingComponent = defineAsyncComponent({
loader: () => import('./Loading.vue'),
loadingComponent: SimpleLoading,
delay: 200
})






