系统需求:
在前端有请求时,并且请求还没有接收到响应时,需要显示个遮罩层,并显示加载状态,来屏蔽用户的操作;等所有请求都完成后,遮罩层消失,用户可以继续操作。
设计方案:
在主组件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组件中添加Watchafter_login_router: '/home', // 登录后跳转路由pathrequest_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
在请求拦截器方法里,更新请求个数统计
mit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] + 1})
在拦截响应器方法和拦截错误的里面分别添加,更新请求个数统计的代码
//返回状态判断(响应拦截器)axios.interceptors.response.use((res) =>{...mit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] - 1})......}, (error) => {...mit('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]mit('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) =>{mit('SET_TMP_VALUE', {name:'request_count',value: store.state.TMP['request_count'] - 1})//对响应数据做些事// 判断返回的数据中是否有token参数,如果有,那么要刷新store里的tokenif(res.data.token){mit('UPDATE_TOKEN', res.data.token);}// SESSION过期if (res.data.code == 1001) {// 清除cookies里的SESSIONCookies.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) => {mit('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}
如果觉得《Vue 单页应用 axios请求时 全局遮罩层设计》对你有帮助,请点赞、收藏,并留下你的观点哦!