Vue 单页应用 axios请求时 全局遮罩层设计

系统需求:

        在前端有请求时,并且请求还没有接收到响应时,需要显示个遮罩层,并显示加载状态,来屏蔽用户的操作;等所有请求都完成后,遮罩层消失,用户可以继续操作。

设计方案:

在主组件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
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
易购商城是一个基于Vue框架开发的前端毕设项目。在该项目中,我使用了VueVuex、Vue Router、Element UI、Axios等技术和库来实现各种功能。 首先,Vue是一种流行的前端框架,它具有响应式的数据绑定和组件化的特性,使得开发者可以轻松构建交互性强、高效的单页应用。 其次,我使用了Vuex来管理应用的状态。Vuex提供了一种集中式的状态管理方案,帮助我管理和共享全局的数据,使得不同组件之间的通信更加便捷。 Vue Router是Vue官方提供的路由管理库,用于实现页面之间的导航和路由跳转。我使用它来定义和管理不同页面之间的跳转逻辑,使得用户可以通过URL来访问和导航各个页面。 Element UI是一套基于Vue的桌面端组件库,它提供了丰富的UI组件和样式,使得我可以快速构建出美观和功能完善的界面。 为了与后端进行数据交互,我使用了Axios库。Axios是一个基于Promise的HTTP客户端,可以在前端与后端进行异步数据交互,使得用户可以实现登录、注册、添加购物车、结算等功能。 最后,我还使用了Vue插件vue-echarts和vue-awesome-swiper来实现商品数据的可视化展示和轮播图功能。这些插件都提供了强大且易用的功能,使得易购商城的用户界面更加丰富和吸引人。 总体来说,通过使用VueVuex、Vue Router、Element UI、Axios等技术和库,我成功地实现了易购商城的前端开发工作,提供了丰富的功能和良好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值