perf: 前端配置Element Plus按需引入,优化Axios错误拦截提示

This commit is contained in:
yml
2026-05-25 02:23:20 +08:00
parent 7d74c0c146
commit 4ebb90870a
5 changed files with 64 additions and 5 deletions
+10
View File
@@ -0,0 +1,10 @@
/* eslint-disable */
/* prettier-ignore */
// @ts-nocheck
// noinspection JSUnusedGlobalSymbols
// Generated by unplugin-auto-import
// biome-ignore lint: disable
export {}
declare global {
}
+24
View File
@@ -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']
}
} }
+21 -1
View File
@@ -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
+3 -3
View File
@@ -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();
+6 -1
View File
@@ -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: {