重构axios与多彩loading,常规loading封装逻辑

This commit is contained in:
初志鑫 2020-07-31 12:45:17 +08:00
parent e2e8506c08
commit 64eecc09bc
7 changed files with 114 additions and 118 deletions

View File

@ -46,5 +46,10 @@
},
"editor.suggest.snippetsPreventQuickSuggestions": false,
"prettier.htmlWhitespaceSensitivity": "ignore",
"prettier.vueIndentScriptAndStyle": true
"prettier.vueIndentScriptAndStyle": true,
"docthis.authorName": "chuzhixin 1204505056@qq.com",
"docthis.includeAuthorTag": true,
"docthis.includeDescriptionTag": true,
"docthis.enableHungarianNotationEvaluation": true,
"docthis.inferTypesFromNames": true
}

View File

@ -162,13 +162,17 @@ const data = [
content: "全局axios请求全面支持Status Code拦截处理",
timestamp: "2020-07-29",
},
{
content: "重构全局loadding加载代码",
timestamp: "2020-07-31",
},
];
export default [
{
url: "/changeLog/getList",
type: "post",
response(config) {
response() {
return {
code: 200,
msg: "success",

View File

@ -56,7 +56,7 @@
"jsencrypt": "^3.0.0-rc.1",
"jsonlint": "^1.6.3",
"lodash": "^4.17.19",
"maptalks": "^0.47.5",
"maptalks": "^0.48.0",
"mapv": "^2.0.56",
"nprogress": "^0.2.0",
"qs": "^6.9.4",
@ -88,7 +88,7 @@
"@vue/cli-plugin-vuex": "^4.4.6",
"@vue/cli-service": "^4.4.6",
"@vue/eslint-config-prettier": "^6.0.0",
"autoprefixer": "^9.8.5",
"autoprefixer": "^9.8.6",
"babel-eslint": "^10.1.0",
"compression-webpack-plugin": "^4.0.0",
"eslint": "^7.5.0",

View File

@ -2,20 +2,20 @@
* @copyright chuzhixin 1204505056@qq.com
* @description 公共布局导出已封装成npm便于此后在线升级当然也存在一定的弊端给开发者自定义增加了一定的困难如果您一定要进行高度自定义请仔细阅读VIP群文档layouts本地化篇
*/
export { default as ColorfullIcon } from "zx-layouts/ColorfullIcon";
export { default as RemixIcon } from "zx-layouts/RemixIcon";
export { default as VabDrag } from "zx-layouts/Drag";
export { default as VabPermissions } from "zx-layouts/Permissions";
export { default as VabQueryForm } from "zx-layouts/VabQueryForm/export";
export { default as Logo } from "zx-layouts/Logo";
export { default as Avatar } from "zx-layouts/Avatar";
export { default as ColorfullIcon } from "./zx-layouts/ColorfullIcon";
export { default as RemixIcon } from "./zx-layouts/RemixIcon";
export { default as VabDrag } from "./zx-layouts/Drag";
export { default as VabPermissions } from "./zx-layouts/Permissions";
export { default as VabQueryForm } from "./zx-layouts/VabQueryForm/export";
export { default as Logo } from "./zx-layouts/Logo";
export { default as Avatar } from "./zx-layouts/Avatar";
export { default as Ad } from "./Ad";
export { default as AppMain } from "zx-layouts/AppMain";
export { default as TagsBar } from "zx-layouts/TagsBar";
export { default as SideBar } from "zx-layouts/SideBar";
export { default as Breadcrumb } from "zx-layouts/Breadcrumb";
export { default as FullScreenBar } from "zx-layouts/FullScreenBar";
export { default as ErrorLog } from "zx-layouts/ErrorLog";
export { default as ThemeBar } from "zx-layouts/ThemeBar";
export { default as TopBar } from "zx-layouts/TopBar";
export { default as NavBar } from "zx-layouts/NavBar";
export { default as AppMain } from "./zx-layouts/AppMain";
export { default as TagsBar } from "./zx-layouts/TagsBar";
export { default as SideBar } from "./zx-layouts/SideBar";
export { default as Breadcrumb } from "./zx-layouts/Breadcrumb";
export { default as FullScreenBar } from "./zx-layouts/FullScreenBar";
export { default as ErrorLog } from "./zx-layouts/ErrorLog";
export { default as ThemeBar } from "./zx-layouts/ThemeBar";
export { default as TopBar } from "./zx-layouts/TopBar";
export { default as NavBar } from "./zx-layouts/NavBar";

View File

@ -1,59 +1,90 @@
import Vue from "vue";
import axios from "axios";
import {
baseURL,
contentType,
debounce,
invalidCode,
messageDuration,
noPermissionCode,
requestTimeout,
successCode,
tokenName,
debounce,
} from "@/config/settings";
import { Loading, Message } from "element-ui";
import store from "@/store";
import qs from "qs";
import router from "@/router";
import _ from "lodash";
import { isArray } from "@/utils/validate";
const service = axios.create({
let loadingInstance;
/**
* @copyright chuzhixin 1204505056@qq.com
* @description 判断当前url是否需要加loading
* @param {*} config
* @returns
*/
const needLoading = (config) => {
let status = false;
debounce.forEach((item) => {
if (Vue.prototype.$baseLodash.includes(config.url, item)) {
status = true;
}
});
return status;
};
/**
* @copyright chuzhixin 1204505056@qq.com
* @description 处理code异常
* @param {*} code
* @param {*} msg
*/
const handleCode = (code, msg) => {
switch (code) {
case invalidCode:
Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, "error");
store.dispatch("user/resetAccessToken").catch(() => {});
break;
case noPermissionCode:
router.push({ path: "/401" }).catch(() => {});
break;
default:
Vue.prototype.$baseMessage(msg || `后端接口${code}异常`, "error");
break;
}
};
const instance = axios.create({
baseURL,
timeout: requestTimeout,
headers: {
"Content-Type": contentType,
},
});
let loadingInstance;
service.interceptors.request.use(
instance.interceptors.request.use(
(config) => {
if (store.getters["user/accessToken"]) {
config.headers[tokenName] = store.getters["user/accessToken"];
}
if (config.data) {
//这里会过滤所有为空、0、false的key如果不需要请自行注释
config.data = _.pickBy(config.data, _.identity);
}
if (process.env.NODE_ENV !== "preview") {
if (contentType === "application/x-www-form-urlencoded;charset=UTF-8") {
if (config.data) {
config.data = qs.stringify(config.data);
}
}
}
const needLoading = () => {
let status = false;
debounce.forEach((item) => {
if (_.includes(config.url, item)) {
status = true;
}
});
return status;
};
if (needLoading()) {
loadingInstance = Loading.service();
//这里会过滤所有为空、0、false的key如果不需要请自行注释
if (config.data)
config.data = Vue.prototype.$baseLodash.pickBy(
config.data,
Vue.prototype.$baseLodash.identity
);
if (
process.env.NODE_ENV !== "preview" &&
contentType === "application/x-www-form-urlencoded;charset=UTF-8" &&
config.data
) {
config.data = qs.stringify(config.data);
}
if (needLoading(config)) {
loadingInstance = Vue.prototype.$baseLoading();
}
return config;
},
(error) => {
@ -61,41 +92,21 @@ service.interceptors.request.use(
}
);
const errorMsg = (message) => {
return Message({
message: message,
type: "error",
duration: messageDuration,
});
};
service.interceptors.response.use(
instance.interceptors.response.use(
(response) => {
if (loadingInstance) {
loadingInstance.close();
}
if (loadingInstance) loadingInstance.close();
const { status, data, config } = response;
const { code, msg } = data;
// 操作正常Code数组
let codeVerificationArray = isArray(successCode)
const codeVerificationArray = isArray(successCode)
? [...successCode]
: [...[successCode]];
// 是否操作正常
if (codeVerificationArray.includes(code)) {
return data;
} else {
switch (code) {
case invalidCode:
errorMsg(msg || `后端接口${code}异常`);
store.dispatch("user/resetAccessToken").catch(() => {});
break;
case noPermissionCode:
router.push({ path: "/401" }).catch(() => {});
break;
default:
errorMsg(msg || `后端接口${code}异常`);
break;
}
handleCode(code, msg);
return Promise.reject(
"vue-admin-beautiful请求异常拦截:" +
JSON.stringify({ url: config.url, code, msg }) || "Error"
@ -103,26 +114,14 @@ service.interceptors.response.use(
}
},
(error) => {
if (loadingInstance) {
loadingInstance.close();
if (loadingInstance) loadingInstance.close();
const { response, message } = error;
if (error.response && error.response.data) {
const { status, data } = response;
handleCode(status, data.msg || message);
return Promise.reject(error);
}
/*网络连接过程异常处理*/
let { message } = error;
if (message === "Network Error") {
message = "后端接口连接异常";
}
if (message.includes("timeout")) {
message = "后端接口请求超时";
}
if (message.includes("Request failed with status code")) {
message = "后端接口" + message.substr(message.length - 3) + "异常";
}
if (error.response) {
const { data } = error.response;
message = data.msg;
}
errorMsg(message || "后端接口未知异常");
return Promise.reject(error);
}
);
export default service;
export default instance;

View File

@ -17,7 +17,7 @@ const install = (Vue, opts = {}) => {
return title;
})();
/* 全局加载层 */
Vue.prototype.$baseLoading = (index, text, callback) => {
Vue.prototype.$baseLoading = (index, text) => {
let loading;
if (!index) {
loading = Loading.service({
@ -33,16 +33,10 @@ const install = (Vue, opts = {}) => {
background: "hsla(0,0%,100%,.8)",
});
}
if (callback) {
callback(loading);
} else {
setTimeout(() => {
loading.close();
}, messageDuration);
}
return loading;
};
/* 全局多彩加载层 */
Vue.prototype.$baseColorfullLoading = (index, text, callback) => {
Vue.prototype.$baseColorfullLoading = (index, text) => {
let loading;
if (!index) {
loading = Loading.service({
@ -73,13 +67,7 @@ const install = (Vue, opts = {}) => {
background: "hsla(0,0%,100%,.8)",
});
}
if (callback) {
callback(loading);
} else {
setTimeout(() => {
loading.close();
}, messageDuration);
}
return loading;
};
/* 全局Message */
Vue.prototype.$baseMessage = (message, type) => {

View File

@ -11,9 +11,6 @@
<el-button type="primary" @click="handleLoading(7)">效果7</el-button>
<el-button type="primary" @click="handleLoading(8)">效果8</el-button>
<el-button type="primary" @click="handleLoading(9)">效果9</el-button>
<el-button type="primary" @click="test()">
全局默认骨架屏(仿支付宝)
</el-button>
<br />
<br />
<br />
@ -41,13 +38,16 @@
},
methods: {
handleLoading(index) {
this.$baseLoading(index);
const Loading = this.$baseLoading(index);
setTimeout(() => {
Loading.close();
}, 3000);
},
handleColorfullLoading(index) {
this.$baseColorfullLoading(index);
},
test() {
location.reload();
const Loading = this.$baseColorfullLoading(index);
setTimeout(() => {
Loading.close();
}, 3000);
},
},
};