vue全局下的loading设置

因为在网上想找有关于vue发送请求时一个全局的 loading 状态,但是苦于没有找到一个很好的案例,所以我根据之前有过的 react umi 中自带的一个全局 loading,翻拍了一个在 vue 中设计一下,虽然不知道自己设计的怎么样,但是今天给想用的小伙伴分享一下我的成果。

(鉴于对新手来说,我新增了补充说明,希望能够详细说明所有的处理流程,本次使用的是vue2 + js的处理方式;欢迎留下你需要知道的问题,我们共同进步,共同设计新方法)

设计想法

首先对于全局的 loading 状态你少不了会用到请求部分,这里我用到的是axios,一般大家应该也都会使用吧,然后我们用的就是vuex,来管理axios发送请求时,接口地址的对应状态,接下来我们就来捋一捋整个的一个流程:
yhl
这次我特意把我项目目录展示出来了-.-,根据这个目录我希望会对你的项目提供到帮助

cloud_meeting
    ├── html                    生产环境包
    ├── public                  静态文件
    ├── src                     源码目录
    |   ├── assets                  模块资源
    |   ├── components              公共组件 ===> (往下有详细目录)*
    |   ├── layouts                 布局组件
    |   ├── request                 请求
    |   |   └── api                  	接口调用 ===> (往下有详细目录)
    |   |   └── apiUrl.js               接口地址
    |   |   └── handleResult.js         集中处理接口返回
    |   |   └── http.js                 ajax二次封装
    |   ├── router                  路由
    |   |   └── index.js                路由配置
    |   ├── store                   vuex状态管理
    |   |   └── modules                 store子模块
    |   |   |   └── account.js              账户中心
    |   |   └── index.js                vuex主模块
    |   ├── style                   公共样式
    |   |   └── common.less             全局自定义样式
    |   |   └── global.less             antd全局样式
    |   |   └── public.less             全局样式变量(颜色与字体)
    |   ├── utils                   公共方法
    |   |   └── excel
    |   |       └── Blob.js
    |   |       └── Export2Excel.js
    |   |   └── errorCode.js             接口返回的错误码提示信息,在git上有最新的,需要在更新版本时重新获取一次
    |   |   └── handleData.js            处理数据样式,转换等方法
    |   |   └── handleQueryData.js       查询各类所需信息
    |   |   └── handleTabelData.js       处理列表数据,搜索数据等
    |   |   └── excel                    导出excel的必要文件
    |   |   └── handleUserInfo.js        处理登录后个人信息,企业信息存储到对应的store中
    |   |   └── uuid.js                  用于登录生成不一样的id,移动端可以识别手机信息,web端则无法获取系统信息,固使用uuid做为登录凭证
    |   ├── views                   页面组件
    |   ├── App.vue                 根组件
    |   ├── main.js                 入口
    |   ├── permission              路由拦截
    ├── test                    测试环境包
    ├── .env.development        开发环境
    ├── .env.production         生产环境
    ├── .env.test               测试环境
    ├── .gitignore              屏蔽提交文件
    ├── babel.config.js         babel语法编译
    ├── package-lock.json       依赖当前版本信息
    ├── package.json            项目依赖基本信息
    ├── vue.config.js           配置
  1. 你需要先配置一个单独的接口地址文件,我这里可能设计的模块较多所以我把每个模块有单独分出来; 在目录 src/request/apiUrl.js创建接口集合
// 配置代理前加前缀使用
const resquest = "";

// 配置所有的接口地址 
const apiConfigUrl = {
    // 会议模块
    meeting: {
        list: `${resquest}/list`,
        delList: `${resquest}/delList`,
        tag: `${resquest}/tagList`,
    }
}

export default apiConfigUrl;
  1. 然后你需要把接口中所涉及到接口地址,提前存到你的vuex中,这样你才能方便在view层中使用他们。目录 src/store/index.js
// An highlighted block
import Vue from "vue";
import Vuex from "vuex";
import apiUrl from "../request/apiConfigUrl";

// 把所有配置的结构地址,都配置到stroe中
let apiList = {};

function setNewApiList(data) {
    for (let key in data) {
        if (typeof data[key] === "string") apiList[data[key]] = false;
        else setNewApiList(data[key]);
    }
}

setNewApiList(apiUrl);

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        Loading: { ...apiList },
    },
    getters: {
        // 获取对应接口请求状态 true 请求中 false 请求结束
        getLoading: (state) => (url) => {
            for (let key in state.Loading) {
                if (key === url) {
                    return state.Loading[key];
                }
            }
            return false;
        },
    },
    mutations: {
        // 设置loading中对应接口的请求状态
        setLoading(state, { url, status }) {
            state.Loading[url] = status;
        },
    },
    actions: {
        // 触发 setLoading 设置
        setLoading({ commit }, data) {
            commit("setLoading", data);
        },
    },
    modules: {},
});

如果你以上步骤对了,那么你在vuetools里面就能看到,你存储后的接口地址了
在这里插入图片描述

  1. 现在你还得配置好你的请求,用来触发在 vuex 中的 actions 的 setLoading,来改变你在 vuex 中存储的对应的接口状态,分别对应的是以下几个地方:
import axios from 'axios';
import store from '../store/index';

// 创建axios实例
let instance = axios.create({
    // 生产开发环境不固定使用浏览器默认截取到的
    // baseURL: process.env.VUE_APP_API_URL, // 域名
    timeout: 1000 * 6,
    withCredentials: true,
    transformResponse: [function transformResponse(data) {
        return jsonlint.parse(data)
    }],
});

// 设置post请求头 formData
instance.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

/**
 * 请求拦截器-
 * 每次请求前, 如果存在token则在请求头中携带token
 */
instance.interceptors.request.use(
    config => {
        //发请求前设置store中存储的接口请求状态
        /**
         * 设置对应接口请求状态对象
         * 然后分别在请求拦截,响应拦截中设置状态
         * 改变store中对应接口的请求状态
         */
        store.dispatch("setLoading", {
            url: `${config.url}`,
            status: true,
        });
		// 中间省略了 很多封装请求的 我会在后续更新请求部分的配置
        return config;
    },
    error => Promise.error(error)
);

// 处理返回后Loading状态,url存在正常返回,反之是异常都会关闭Loading状态
function handleResponseLoading(url) {
    if (!!url) {
        let apiUrl = url;

        if (url.indexOf("?") !== -1) {
            apiUrl = url.split("?")[0];
        }

        // 如果成功则需要, 设置对应接口loading状态
        store.dispatch("setLoading", { url: apiUrl, status: false });
    } else {
        for (let l in store.state.Loading) {
            store.state.Loading[l] = false
        }
    }

}
// 响应拦截器
instance.interceptors.response.use(
    // 请求成功
    res => {
        // Get Put 请求中参数时拼接到地址栏的,所以对应的接口状态中应去掉?后的参数,才能取消请求状态
        handleResponseLoading(res.config.url)

        return Promise.resolve(data);
    },

    // 请求失败
    error => {
        handleResponseLoading(config.url)
    }
);

export {
    instance as axios,
};
  1. 最后在你的view层面你就可以在每次发送请求是接收你的对应接口状态,具体getter,我在vuex中已经设置好了,他主要的目的就是 vuex 状态更新后自动就会触发 getter 属性给 view 层更新渲染的。
computed: {
   loading() {
       // 获取对应接口loading状态,需要传对应接口的接口地址
       return (
           this.$store.getters.getLoading(this.apiUrl.meeting.list) ||
           this.$store.getters.getLoading(this.apiUrl.meeting.delList)
       );
   },
},
  1. 现在你的 loading 属性就跟你的接口挂钩了,只要你在请求中触发了你写在 loading 中接口,loading的值就会发生变化了,至于怎么触发你的动画,就看你怎么写了,至于我是怎么直接使用 this.apiUrl ,我把接口的配置文件 apiConfigUrl.js 混入到全局组件了
import apiUrl from './request/apiConfigUrl'
// 把apiUrl接口地址,全局混入到每个组件中 目录 src/main.js
Vue.mixin({
  data() {
    return {
      apiUrl
    }
  },
})

这样你就不需要每个组件都去引用了,不知这样写好不好,反正真的很方便

后面我会出一些有关vuex,axios的使用方法,请持续关注哦!

Logo

前往低代码交流专区

更多推荐