独立封装Vue脚手架,包括axios封装、动态菜单、权限路由、webpack优化、eslint配置等。

1.axios封装

拦截器

  1. import axios from "axios";
  2. import { Notification, MessageBox, Message } from "element-ui";
  3. import store from "@/store";
  4. import { getToken } from "@/utils/auth";
  5. import errorCode from "@/utils/errorCode";
  6. import { tansParams } from "@/utils/ruoyi";
  7. axios.defaults.headers["Content-Type"] = "application/json;charset=utf-8";
  8. // 创建axios实例
  9. const service = axios.create({
  10. // axios中请求配置有baseURL选项,表示请求URL公共部分
  11. baseURL: process.env.VUE_APP_BASE_API,
  12. // 超时
  13. timeout: 10000,
  14. });
  15. // request拦截器
  16. service.interceptors.request.use(
  17. (config) => {
  18. const isToken = (config.headers || {}).isToken === false;
  19. if (getToken() && !isToken) {
  20. config.headers["Authorization"] = "Bearer " + getToken(); // 让每个请求携带自定义token 请根据实际情况自行修改
  21. }
  22. return config;
  23. },
  24. (error) => {
  25. console.log(error);
  26. Promise.reject(error);
  27. }
  28. );
  29. // 响应拦截器
  30. service.interceptors.response.use(
  31. (res) => {
  32. const code = res.data.code || 200;
  33. const message = errorCode[code] || res.data.msg || errorCode["default"];
  34. if (code === 401) {
  35. MessageBox.confirm(
  36. "登录状态已过期,您可以继续留在该页面,或者重新登录",
  37. "系统提示",
  38. {
  39. confirmButtonText: "重新登录",
  40. cancelButtonText: "取消",
  41. type: "warning",
  42. }
  43. ).then(() => {
  44. store.dispatch("LogOut").then(() => {
  45. location.reload(); // 为了重新实例化vue-router对象 避免bug
  46. });
  47. });
  48. } else if (code === 500) {
  49. Message({
  50. message: message,
  51. type: "error",
  52. });
  53. return Promise.reject(new Error(message));
  54. } else if (code !== 200) {
  55. Notification.error({
  56. title: message,
  57. });
  58. return Promise.reject("error");
  59. } else {
  60. return res.data;
  61. }
  62. },
  63. (error) => {
  64. if (error.response?.status === 401) {
  65. store.dispatch("LogOut").then(() => {
  66. location.reload(); // 为了重新实例化vue-router对象 避免bug
  67. });
  68. } else {
  69. Message({
  70. message: error.message,
  71. type: "error",
  72. duration: 5 * 1000,
  73. });
  74. return Promise.reject(error);
  75. }
  76. }
  77. );
  78. // 通用下载方法
  79. export function download(url, params, filename) {
  80. return service
  81. .post(url, params, {
  82. transformRequest: [
  83. (params) => {
  84. return tansParams(params);
  85. },
  86. ],
  87. responseType: "blob",
  88. })
  89. .then((data) => {
  90. const content = data;
  91. const blob = new Blob([content]);
  92. if ("download" in document.createElement("a")) {
  93. const elink = document.createElement("a");
  94. elink.download = filename;
  95. elink.style.display = "none";
  96. elink.href = URL.createObjectURL(blob);
  97. document.body.appendChild(elink);
  98. elink.click();
  99. URL.revokeObjectURL(elink.href);
  100. document.body.removeChild(elink);
  101. } else {
  102. navigator.msSaveBlob(blob, filename);
  103. }
  104. })
  105. .catch((r) => {
  106. console.error(r);
  107. });
  108. }
  109. export default service;

2.动态菜单、权限路由

3.webpack优化

4.登录鉴权