升级依赖 & 修复 TS 类型解析 & 适配 element-plus 样式变化

依赖升级:
- element-plus 2.2.28 -> 2.13.5
- vue 3.2.45 -> 3.5.30
- vue-router 4.0.11 -> 4.6.4
- axios 0.22 -> 1.13.6
- echarts 5.2.1 -> 5.6.0
- hls.js 1.3 -> 1.6.15
- typescript 4.5.5 -> 5.9.3

破坏性变更修复:
- axios 1.x: config.headers.token= 改为 config.headers.set()
- element-plus locale 路径: lib/ -> es/
- Article.vue: Node 改为具名导入 { Node }
- main.ts: 路由守卫参数补全显式类型声明
- SystemConfig.vue: 移除废弃的 clearValidate 包装函数

TypeScript 配置修复 (tsconfig.json):
- moduleResolution: node -> bundler (支持 exports 字段, 解决 vue-router .mts 类型文件)
- 新增 skipLibCheck: true (规避第三方库内部类型冲突)
- 新增 vuex paths 映射 (vuex exports 字段缺少 types 条件)

样式适配 (common.less):
- el-dialog 新增 padding: 0, 消除升级后产生的白边
- el-form--inline 内 el-select 补 min-width: 160px, 修复搜索栏下拉框过窄问题

清理:
- 删除 src/vuex.d.ts (已无用的 vuex store 类型扩充文件)
This commit is contained in:
灌糖包子 2026-03-20 00:33:09 +08:00
parent 2c8789b8cb
commit 90a6153776
Signed by: sookie
GPG Key ID: 0599BECB75C1E68D
13 changed files with 895 additions and 662 deletions

800
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -6,17 +6,17 @@
"build": "vue-cli-service build"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.10",
"axios": "^0.22.0",
"echarts": "^5.2.1",
"element-plus": "^2.2.28",
"hls.js": "^1.3.0",
"hyperdown": "^2.4.29",
"moment": "^2.29.1",
"@element-plus/icons-vue": "^2.3.2",
"axios": "^1.13.6",
"echarts": "^5.6.0",
"element-plus": "^2.13.5",
"hls.js": "^1.6.15",
"hyperdown": "^2.4.31",
"moment": "^2.30.1",
"pretty-bytes": "^5.6.0",
"vue": "^3.2.45",
"vue-router": "^4.0.11",
"vuex": "^4.0.2"
"vue": "^3.5.30",
"vue-router": "^4.6.4",
"vuex": "^4.1.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.0",
@ -24,9 +24,9 @@
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"less": "^4.0.0",
"less": "^4.6.4",
"less-loader": "^8.0.0",
"typescript": "~4.5.5",
"typescript": "^5.4.0",
"unplugin-auto-import": "^0.12.1",
"unplugin-vue-components": "^0.22.12"
},

View File

@ -7,7 +7,7 @@
</template>
<script setup lang="ts">
import zhCn from 'element-plus/lib/locale/lang/zh-cn'
import zhCn from 'element-plus/es/locale/lang/zh-cn'
const locale = zhCn
</script>

View File

@ -2,6 +2,7 @@ import { createApp } from 'vue'
import App from './App.vue'
import { router, filterExclude } from './router'
import store from './store'
import type { RouteLocationNormalized, NavigationGuardNext } from 'vue-router'
import { ElLoading } from 'element-plus'
import 'element-plus/theme-chalk/el-message.css'
@ -9,7 +10,7 @@ import 'element-plus/theme-chalk/el-message-box.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
// 全局路由导航前置守卫
router.beforeEach(function (to, from, next) {
router.beforeEach(function (to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext) {
if (to.meta?.title) {
store.commit('addTab', { title: to.meta.title, path: to.path, name: to.name })
}

View File

@ -147,6 +147,7 @@ html, body, #app, .layout {
.el-dialog {
border-radius: 12px;
overflow: hidden;
padding: 0 !important;
.el-dialog__header {
background: var(--el-fill-color-light);
@ -177,6 +178,10 @@ html, body, #app, .layout {
.el-form-item {
margin-bottom: 0;
}
.el-select {
min-width: 160px;
}
}
.search-panel {
margin-bottom: 14px;

View File

@ -10,8 +10,8 @@ const http = axios.create({
// 添加请求拦截器
http.interceptors.request.use(config => {
const token = store.state.loginInfo.token
if (token !== null && config.headers) {
config.headers.token = token
if (token !== null) {
config.headers.set('token', token)
}
return config
}, err => {

View File

@ -149,7 +149,7 @@
</template>
<script setup lang="ts">
import { ref, reactive } from 'vue'
import { ref } from 'vue'
import { useStore } from 'vuex'
import { useBaseList } from '@/model/baselist'
import { MsgResult, Page } from '@/model/common.dto'

View File

@ -85,7 +85,7 @@ import { SourceImageModel } from '@/model/api/source-image'
import http from '@/utils/http'
const store = useStore()
const { loading, total, search, setLoadData, loadDataBase, reset, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new Page())
const { loading, total, search, setLoadData, pageChange, pageSizeChange, datetimeFormat } = useBaseList(new Page())
const allowUploadExt = ['jpg', 'jpeg', 'png', 'svg', 'ico']
const sourceImageData = ref<SourceImageModel[]>([])

View File

@ -119,7 +119,7 @@ import { useStore } from 'vuex'
import hyperdown from 'hyperdown'
import { ArticleModel, TreeNodeData, TreeNodeSource } from '@/model/system/article'
import { ElMessage, ElMessageBox } from 'element-plus'
import Node from 'element-plus/lib/components/tree/src/model/node'
import { Node } from 'element-plus/lib/components/tree/src/model/node'
import { useBaseList } from '@/model/baselist'
import { Page, MsgResult } from '@/model/common.dto'
import http from '@/utils/http'

View File

@ -56,13 +56,12 @@
</div>
</template>
<script setup lang="ts">
import { ref, nextTick } from 'vue'
import { ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import moment from 'moment'
import http from '@/utils/http'
import SystemConfigAdd from './SystemConfigAdd.vue'
import { SystemConfigModel } from '@/model/system/system-config'
import { VForm } from '@/types'
const modalLoading = ref(false)
const loading = ref(false)
@ -133,12 +132,6 @@ function remove(row: SystemConfigModel) {
}).catch(() => {})
}
function clearValidate() {
nextTick(() => {
addForm.value?.configForm?.clearValidate()
})
}
function datetimeFormat(dateStr: string) {
return dateStr ? moment(dateStr).format('YYYY-MM-DD HH:mm:ss') : null
}

10
src/vuex.d.ts vendored
View File

@ -1,10 +0,0 @@
import { ComponentCustomProperties } from 'vue'
import { Store } from 'vuex'
import { StateType } from './store/types'
declare module '@vue/runtime-core' {
// provide typings for `this.$store`
interface ComponentCustomProperties {
$store: Store<StateType>
}
}

View File

@ -3,8 +3,9 @@
"target": "esnext",
"useDefineForClassFields": true,
"module": "esnext",
"moduleResolution": "node",
"moduleResolution": "bundler",
"strict": true,
"skipLibCheck": true,
"jsx": "preserve",
"sourceMap": true,
"resolveJsonModule": true,
@ -14,7 +15,8 @@
"allowJs": true,
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
"@/*": ["src/*"],
"vuex": ["node_modules/vuex/types/index.d.ts"]
}
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]

688
yarn.lock

File diff suppressed because it is too large Load Diff