vue全局下的loading设置
vue全局下的loading设置因为在网上想找有关于vue发送请求时一个全局的 loading 状态,但是苦于没有找到一个很好的案例,所以我根据之前有过的 react umi 中自带的一个全局 loading,翻拍了一个在 vue 中设计一下,虽然不知道自己设计的怎么样,但是今天给想用的小伙伴分享一下我的成果。设计想法首先对于全局的 loading 状态你少不了会用到请求部分,这里我用到的是axi
·
vue全局下的loading设置
因为在网上想找有关于vue发送请求时一个全局的 loading 状态,但是苦于没有找到一个很好的案例,所以我根据之前有过的 react umi 中自带的一个全局 loading,翻拍了一个在 vue 中设计一下,虽然不知道自己设计的怎么样,但是今天给想用的小伙伴分享一下我的成果。
(鉴于对新手来说,我新增了补充说明,希望能够详细说明所有的处理流程,本次使用的是vue2 + js的处理方式;欢迎留下你需要知道的问题,我们共同进步,共同设计新方法)
设计想法
首先对于全局的 loading 状态你少不了会用到请求部分,这里我用到的是axios,一般大家应该也都会使用吧,然后我们用的就是vuex,来管理axios发送请求时,接口地址的对应状态,接下来我们就来捋一捋整个的一个流程:
这次我特意把我项目目录展示出来了-.-,根据这个目录我希望会对你的项目提供到帮助
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 配置
- 你需要先配置一个单独的接口地址文件,我这里可能设计的模块较多所以我把每个模块有单独分出来; 在目录 src/request/apiUrl.js创建接口集合
// 配置代理前加前缀使用
const resquest = "";
// 配置所有的接口地址
const apiConfigUrl = {
// 会议模块
meeting: {
list: `${resquest}/list`,
delList: `${resquest}/delList`,
tag: `${resquest}/tagList`,
}
}
export default apiConfigUrl;
- 然后你需要把接口中所涉及到接口地址,提前存到你的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里面就能看到,你存储后的接口地址了
- 现在你还得配置好你的请求,用来触发在 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,
};
- 最后在你的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)
);
},
},
- 现在你的 loading 属性就跟你的接口挂钩了,只要你在请求中触发了你写在 loading 中接口,loading的值就会发生变化了,至于怎么触发你的动画,就看你怎么写了,至于我是怎么直接使用 this.apiUrl ,我把接口的配置文件 apiConfigUrl.js 混入到全局组件了
import apiUrl from './request/apiConfigUrl'
// 把apiUrl接口地址,全局混入到每个组件中 目录 src/main.js
Vue.mixin({
data() {
return {
apiUrl
}
},
})
这样你就不需要每个组件都去引用了,不知这样写好不好,反正真的很方便
后面我会出一些有关vuex,axios的使用方法,请持续关注哦!
更多推荐
已为社区贡献1条内容
所有评论(0)