Vue 单页应用 axios请求时 全局遮罩层设计
系统需求:在前端有请求时,并且请求还没有接收到响应时,需要显示个遮罩层,并显示加载状态,来屏蔽用户的操作;等所有请求都完成后,遮罩层消失,用户可以继续操作。设计方案:在主组件App.vue里,我们加一个遮罩层;在store.state里加一个用来统计当前正在请求的个数 request_count ,这样我们就可全局来更新该变量,当有请求时 request_count + 1,当前有请求返回时req
·
系统需求:
在前端有请求时,并且请求还没有接收到响应时,需要显示个遮罩层,并显示加载状态,来屏蔽用户的操作;等所有请求都完成后,遮罩层消失,用户可以继续操作。
设计方案:
在主组件App.vue里,我们加一个遮罩层;
在store.state里加一个用来统计当前正在请求的个数 request_count ,这样我们就可全局来更新该变量,当有请求时 request_count + 1,当前有请求返回时request_count - 1 。
设计效果:
1、store/index.js
这里,我们把 request_count 定义在 $store.state.TMP 里,方便操作,全局的临时变量,我们项目开发要求约定都定义在TMP这里。
// 临时变量
TMP: {
do_close_page: false, // 用来所有自定义标签页上的关闭按钮控制标签页的关闭,在App组件中添加Watch
after_login_router: '/home', // 登录后跳转路由path
request_count: 0, // 当前正在请求数
loadingBar:false,
session_id:'',
},
TMP的更新方法
// 用来更新 TMP 里变量的方法
SET_TMP_VALUE(state, item) {
state.TMP[item.name] = item.value;
},
2、App.vue
加一个遮罩层的样式通过 $store.state.TMP.request_count > 0 来控制显示
<div v-if="$store.state.TMP.request_count > 0">
<div style="position: fixed; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 99999; background: #eee; opacity: 0.5;"></div>
<div style="font-size:50px; text-align:center; position: fixed; top: 0px; left: 0px; right: 0px; bottom: 0px; z-index: 99999;">
<i class="fa fa-spinner fa-spin" style="margin-top:20%;"></i>
</div>
</div>
3、https.js
导入vuex配置文件
import store from './store/index.js'
axios
在请求拦截器方法里,更新请求个数统计
store.commit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] + 1})
在拦截响应器方法和拦截错误的里面分别添加,更新请求个数统计的代码
//返回状态判断(响应拦截器) axios.interceptors.response.use((res) =>{ ... store.commit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] - 1}) ... ... }, (error) => { ... store.commit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] - 1}) ... });
https 完整代码:
import axios from 'axios'
import qs from 'qs'
import store from './store/index.js'
import router from './router';
import Vue from 'vue'
import Cookies from 'js-cookie'
// 加载登录框插件
import loginbox from './plugins/loginbox/index.js'
Vue.use(loginbox)
import {Message} from 'view-design';
axios.defaults.timeout = 1200000; // 响应时间
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'; //配置请求头
// 在开发模式和生产模式环境变量文件中分别配置[VUE_APP_API_URL]参数值
//axios.defaults.baseURL = process.env.VUE_APP_API_URL;
//POST传参序列化(添加请求拦截器)
axios.interceptors.request.use((config) => {
// session变了后,要重新加载页面
if(store.state.TMP.session_id != '' && store.state.TMP.session_id != Cookies.get('S_YBS')){
window.location = window.location.href.replace(/#/g,"vue-router");
return false;
}
config.headers['X-Requested-With'] = 'XMLHttpRequest'
let regex = /.*XSRF-TOKEN=([^;.]*).*$/
config.headers['X-XSRF-TOKEN'] = document.cookie.match(regex) === null ? null : document.cookie.match(regex)[1]
store.commit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] + 1})
return config;
},(error) =>{
console.log('错误的传参');
Message.error({content:'错误的传参', duration:4});
return Promise.reject(error);
});
//返回状态判断(添加响应拦截器)
axios.interceptors.response.use((res) =>{
store.commit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] - 1})
//对响应数据做些事
// 判断返回的数据中是否有token参数,如果有,那么要刷新store里的token
if(res.data.token){
store.commit('UPDATE_TOKEN', res.data.token);
}
// SESSION过期
if (res.data.code == 1001) {
// 清除cookies里的SESSION
Cookies.remove('S_YBS');
// 刷新页面
window.location = window.location.href.replace(/#/g,"vue-router");
}else if(res.data.code == 1005){
// 未登录,跳转到登录页
window.location = window.location.href.replace(/#/g,"vue-router");
}
if (res.data.err){
console.log(res.data);
Message.error({content:res.data.msg || '服务端程序错误', duration:4});
return Promise.reject(res.data);
}
return res;
}, (error) => {
store.commit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] - 1})
console.log('请求失败');
Message.error({content:'请求失败', duration:4});
return Promise.reject(error);
});
//返回一个Promise(发送post请求)
export function fetchPost(url, params) {
return new Promise((resolve, reject) => {
axios.post(url, params)
.then(response => {
resolve(response);
}, err => {
reject(err);
})
.catch((error) => {
reject(error)
})
})
}
返回一个Promise(发送get请求)
export function fetchGet(url, param) {
return new Promise((resolve, reject) => {
axios.get(url, {params: param})
.then(response => {
resolve(response)
}, err => {
reject(err)
})
.catch((error) => {
reject(error)
})
})
}
// 设置axios请求的默认头信息
export function setHeaders(name, val){
axios.defaults.headers.post[name] = val || "";
}
export default {
fetchPost,
fetchGet,
setHeaders
}
更多推荐
已为社区贡献1条内容
所有评论(0)