业务需求:
- 请求前全局加载loading,多接口请求结束后再关闭loading;
- 可指定接口使用;
- 可全局显示(不遮挡导航栏仅在内容页显示) 或 指定页面使用;
其他:
- 本文涉及Vue 、ElementUI、 Vuex
1.配置需要全局loading的API
...
// xxx接口
export function getList(data,showLoading = false) {
return service({
url: serverName + '/getList',
method: 'post',
data: Qs.stringify(data),
showLoading, // 添加showLoading参数
})
}
...
2.修改axios.js文件
// 请求拦截器
request.interceptors.request.use( config => {
if (config.showLoading) {
store.dispatch('setLoding', true) // 根据showLoading参数判断是否需要全局显示loaidng
}
...
return config
},
error => { return Promise.reject(error) } )
// 响应拦截器
request.interceptors.response.use( (res) => {
if (res.showLoading) {
store.dispatch('setLoding', false) // 响应结束则关闭loading
}
...
return result
}
3.Vuex (记录loadingCount)
- 添加loading.js文件(本项目文件路径: src\store\modules\loading.js)
const state = {
loadingCount: 0,
}
const mutations = {
SET_LOADING: (state, isShow) => { // 需要全局loading的则loadingCount+1,否则loadingCount-1
isShow ? ++state.loadingCount : --state.loadingCount
},
CLEAR_LOADING: (state) => {
state.loadingCount = 0 // 当loadingCount等于0时关闭loading效果
},
}
const actions = {
setLoding({ commit }, boolean) {
commit('SET_LOADING', boolean)
},
clearLoading({ commit }) {
commit('CLEAR_LOADING')
},
}
export default {
namespaced: true,
state,
mutations,
actions,
}
- 修改getters.js
4.在页面中添加loading
- 在layout.vue下或其他组件下添加(这里使用elementUI的loading组件):
<div class="main" v-loading="loading" :element-loading-text="loadingText">
...
</div>
import { mapGetters } from 'vuex'
export default {
data () {
loading:false,
loadingText:'数据加载中...'
},
computed: { ...mapState(['loadingCount']) },
watch:{
loadingCount(newval){
this.loading= newval > 0
},
}
- 调用接口页:
created(){
this.getData()
},
methods: {
getData(){
const param={
...
}
getList(param,true).then(res=>{
//
}).finally(()=>{
})
}
}
5.注意:在路由跳转时要关闭全局loading,不然影响交互体验
router.beforeEach((to, from, next) => {
store.dispatch('clearLoading') //清除全局loading
...
next()
})
补充其他方法:接口较少可直接使用Promise.all()实现
getData(){
const loading = this.$loading({
target: '.content',
text: '数据加载中...',
})
const promiseArray = [
//1.获取表格列宽
new Promise((resolve) => {
if (JSON.stringify(this.colwidthForm) !== '{}') resolve()
this.getColwidth().then((res) => {
this.colwidthForm = res || {}
resolve()
})
}),
//2.查询字段数据
new Promise((resolve) => {
this.getFieldInfo().then((res) => {
this.fields = res || []
resolve()
})
}),
...
]
Promise.all(promiseArray).then(() => {
loading.close() //等所有接口响应完则关闭loading
})
}