perf: 前端配置Element Plus按需引入,优化Axios错误拦截提示
This commit is contained in:
Vendored
+10
@@ -0,0 +1,10 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
/* prettier-ignore */
|
||||||
|
// @ts-nocheck
|
||||||
|
// noinspection JSUnusedGlobalSymbols
|
||||||
|
// Generated by unplugin-auto-import
|
||||||
|
// biome-ignore lint: disable
|
||||||
|
export {}
|
||||||
|
declare global {
|
||||||
|
|
||||||
|
}
|
||||||
Vendored
+24
@@ -11,6 +11,27 @@ export {}
|
|||||||
/* prettier-ignore */
|
/* prettier-ignore */
|
||||||
declare module 'vue' {
|
declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
|
ElAlert: typeof import('element-plus/es')['ElAlert']
|
||||||
|
ElButton: typeof import('element-plus/es')['ElButton']
|
||||||
|
ElCarousel: typeof import('element-plus/es')['ElCarousel']
|
||||||
|
ElCarouselItem: typeof import('element-plus/es')['ElCarouselItem']
|
||||||
|
ElDialog: typeof import('element-plus/es')['ElDialog']
|
||||||
|
ElEmpty: typeof import('element-plus/es')['ElEmpty']
|
||||||
|
ElForm: typeof import('element-plus/es')['ElForm']
|
||||||
|
ElFormItem: typeof import('element-plus/es')['ElFormItem']
|
||||||
|
ElIcon: typeof import('element-plus/es')['ElIcon']
|
||||||
|
ElInput: typeof import('element-plus/es')['ElInput']
|
||||||
|
ElInputNumber: typeof import('element-plus/es')['ElInputNumber']
|
||||||
|
ElOption: typeof import('element-plus/es')['ElOption']
|
||||||
|
ElPagination: typeof import('element-plus/es')['ElPagination']
|
||||||
|
ElRadioButton: typeof import('element-plus/es')['ElRadioButton']
|
||||||
|
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
|
||||||
|
ElSelect: typeof import('element-plus/es')['ElSelect']
|
||||||
|
ElSwitch: typeof import('element-plus/es')['ElSwitch']
|
||||||
|
ElTable: typeof import('element-plus/es')['ElTable']
|
||||||
|
ElTableColumn: typeof import('element-plus/es')['ElTableColumn']
|
||||||
|
ElTag: typeof import('element-plus/es')['ElTag']
|
||||||
|
ElTimePicker: typeof import('element-plus/es')['ElTimePicker']
|
||||||
RouterLink: typeof import('vue-router')['RouterLink']
|
RouterLink: typeof import('vue-router')['RouterLink']
|
||||||
RouterView: typeof import('vue-router')['RouterView']
|
RouterView: typeof import('vue-router')['RouterView']
|
||||||
VanButton: typeof import('vant/es')['Button']
|
VanButton: typeof import('vant/es')['Button']
|
||||||
@@ -29,4 +50,7 @@ declare module 'vue' {
|
|||||||
VanSwipeItem: typeof import('vant/es')['SwipeItem']
|
VanSwipeItem: typeof import('vant/es')['SwipeItem']
|
||||||
VanTag: typeof import('vant/es')['Tag']
|
VanTag: typeof import('vant/es')['Tag']
|
||||||
}
|
}
|
||||||
|
export interface GlobalDirectives {
|
||||||
|
vLoading: typeof import('element-plus/es')['ElLoadingDirective']
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,11 @@
|
|||||||
import axios, { type AxiosResponse, type InternalAxiosRequestConfig } from 'axios'
|
import axios, { type AxiosResponse, type InternalAxiosRequestConfig } from 'axios'
|
||||||
|
import { ElMessage } from 'element-plus'
|
||||||
|
|
||||||
|
declare module 'axios' {
|
||||||
|
export interface AxiosRequestConfig {
|
||||||
|
silent?: boolean
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
import {
|
import {
|
||||||
clearAuthStorage,
|
clearAuthStorage,
|
||||||
@@ -30,7 +37,10 @@ type RefreshState = {
|
|||||||
pendingRequests: RetryRequest[]
|
pendingRequests: RetryRequest[]
|
||||||
}
|
}
|
||||||
|
|
||||||
type RetriableRequestConfig = InternalAxiosRequestConfig & { _retry?: boolean }
|
type RetriableRequestConfig = InternalAxiosRequestConfig & {
|
||||||
|
_retry?: boolean
|
||||||
|
silent?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
const refreshStates: Record<AuthScope, RefreshState> = {
|
const refreshStates: Record<AuthScope, RefreshState> = {
|
||||||
user: {
|
user: {
|
||||||
@@ -103,6 +113,10 @@ apiClient.interceptors.response.use(
|
|||||||
async (error) => {
|
async (error) => {
|
||||||
const originalRequest = error.config as RetriableRequestConfig | undefined
|
const originalRequest = error.config as RetriableRequestConfig | undefined
|
||||||
if (!originalRequest || error?.response?.status !== 401 || originalRequest._retry) {
|
if (!originalRequest || error?.response?.status !== 401 || originalRequest._retry) {
|
||||||
|
if (originalRequest && !originalRequest.silent) {
|
||||||
|
const msg = error.response?.data?.message || error.message || '网络连接异常,请稍后重试'
|
||||||
|
ElMessage.error(msg)
|
||||||
|
}
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +124,9 @@ apiClient.interceptors.response.use(
|
|||||||
const scope = getRequestScope(requestUrl)
|
const scope = getRequestScope(requestUrl)
|
||||||
if (isRefreshRequest(requestUrl)) {
|
if (isRefreshRequest(requestUrl)) {
|
||||||
redirectToLogin(scope)
|
redirectToLogin(scope)
|
||||||
|
if (originalRequest && !originalRequest.silent) {
|
||||||
|
ElMessage.error('登录已失效,请重新登录')
|
||||||
|
}
|
||||||
return Promise.reject(error)
|
return Promise.reject(error)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -134,6 +151,9 @@ apiClient.interceptors.response.use(
|
|||||||
} catch (refreshError) {
|
} catch (refreshError) {
|
||||||
rejectPendingRequests(scope, refreshError)
|
rejectPendingRequests(scope, refreshError)
|
||||||
redirectToLogin(scope)
|
redirectToLogin(scope)
|
||||||
|
if (originalRequest && !originalRequest.silent) {
|
||||||
|
ElMessage.error('会话已过期,请重新登录')
|
||||||
|
}
|
||||||
return Promise.reject(refreshError)
|
return Promise.reject(refreshError)
|
||||||
} finally {
|
} finally {
|
||||||
state.refreshing = false
|
state.refreshing = false
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import "element-plus/dist/index.css";
|
import "element-plus/theme-chalk/el-message.css";
|
||||||
|
import "element-plus/theme-chalk/el-message-box.css";
|
||||||
import "vant/lib/index.css";
|
import "vant/lib/index.css";
|
||||||
import "./styles/base.css";
|
import "./styles/base.css";
|
||||||
|
|
||||||
import ElementPlus from "element-plus";
|
|
||||||
import { createPinia } from "pinia";
|
import { createPinia } from "pinia";
|
||||||
import { createApp } from "vue";
|
import { createApp } from "vue";
|
||||||
|
|
||||||
@@ -14,7 +14,7 @@ import { useSessionStore } from "./stores/session";
|
|||||||
const app = createApp(App);
|
const app = createApp(App);
|
||||||
const pinia = createPinia();
|
const pinia = createPinia();
|
||||||
|
|
||||||
app.use(pinia).use(router).use(ElementPlus);
|
app.use(pinia).use(router);
|
||||||
|
|
||||||
window.addEventListener("auth-storage-changed", () => {
|
window.addEventListener("auth-storage-changed", () => {
|
||||||
useSessionStore(pinia).syncFromStorage();
|
useSessionStore(pinia).syncFromStorage();
|
||||||
|
|||||||
@@ -2,14 +2,19 @@ import { fileURLToPath, URL } from "node:url";
|
|||||||
|
|
||||||
import vue from "@vitejs/plugin-vue";
|
import vue from "@vitejs/plugin-vue";
|
||||||
import { defineConfig } from "vite";
|
import { defineConfig } from "vite";
|
||||||
|
import AutoImport from "unplugin-auto-import/vite";
|
||||||
import Components from "unplugin-vue-components/vite";
|
import Components from "unplugin-vue-components/vite";
|
||||||
|
import { ElementPlusResolver } from "unplugin-vue-components/resolvers";
|
||||||
import { VantResolver } from "@vant/auto-import-resolver";
|
import { VantResolver } from "@vant/auto-import-resolver";
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
plugins: [
|
plugins: [
|
||||||
vue(),
|
vue(),
|
||||||
|
AutoImport({
|
||||||
|
resolvers: [ElementPlusResolver()],
|
||||||
|
}),
|
||||||
Components({
|
Components({
|
||||||
resolvers: [VantResolver()],
|
resolvers: [ElementPlusResolver(), VantResolver()],
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
resolve: {
|
resolve: {
|
||||||
|
|||||||
Reference in New Issue
Block a user