Browse Source

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

初志鑫 4 years ago
parent
commit
64eecc09bc

+ 6 - 1
.vscode/settings.json

@@ -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
 }

+ 5 - 1
mock/controller/changeLog.js

@@ -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",

+ 2 - 2
package.json

@@ -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",

+ 16 - 16
src/layouts/components/index.js

@@ -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";

+ 73 - 74
src/utils/request.js

@@ -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();
-    }
-    /*网络连接过程异常处理*/
-    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 (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);
     }
-    if (error.response) {
-      const { data } = error.response;
-      message = data.msg;
-    }
-    errorMsg(message || "后端接口未知异常");
-    return Promise.reject(error);
   }
 );
-export default service;
+
+export default instance;

+ 4 - 16
src/utils/vab.js

@@ -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) => {

+ 8 - 8
src/views/vab/loading/index.vue

@@ -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);
       },
     },
   };