当前位置:   article > 正文

vue全局下的loading设置_loading怎么和接口同步

loading怎么和接口同步

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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  1. 你需要先配置一个单独的接口地址文件,我这里可能设计的模块较多所以我把每个模块有单独分出来; 在目录 src/request/apiUrl.js创建接口集合
// 配置代理前加前缀使用
const resquest = "";

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

export default apiConfigUrl;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  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: {},
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48

如果你以上步骤对了,那么你在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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  1. 现在你的 loading 属性就跟你的接口挂钩了,只要你在请求中触发了你写在 loading 中接口,loading的值就会发生变化了,至于怎么触发你的动画,就看你怎么写了,至于我是怎么直接使用 this.apiUrl ,我把接口的配置文件 apiConfigUrl.js 混入到全局组件了
import apiUrl from './request/apiConfigUrl'
// 把apiUrl接口地址,全局混入到每个组件中 目录 src/main.js
Vue.mixin({
  data() {
    return {
      apiUrl
    }
  },
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/218894
推荐阅读
相关标签
  

闽ICP备14008679号