vue-element-admin (github.com/PanJiaChen/vue-element-admin) · 生成于 2026/9/17 16:41:29 · 耗时 52ms| 级别 | 检测项 | 命中 | 权重 | 处置建议 |
|---|---|---|---|---|
| high | beforeDestroy / destroyed 生命周期 | 20 | ×2 | Vue 3 重命名为 beforeUnmount / unmounted,改名字即可,但要逐一确认清理逻辑 |
| high | .sync 修饰符 | 14 | ×1 | Vue 3 移除 .sync,改为 v-model:propName;子组件 emit 名从 update:xxx 保持一致 |
| high | slot-scope / slot="name" 旧插槽语法 | 98 | ×3 | Vue 3 只认 v-slot;<template slot-scope="x"> 要改成 <template #default="x"> |
| high | filters 过滤器 | 14 | ×2 | Vue 3 移除 filters 选项,改成 computed 或纯函数调用(模板里写 {{ fmt(x) }}) |
| high | Vue 全局 API(prototype / use / set ...) | 19 | ×3 | Vue 3 改为 app.use / app.config.globalProperties;Vue.set|delete 直接删除(响应式系统已覆盖) |
| high | $on / $off / $once / $listeners / $children | 4 | ×3 | Vue 3 移除实例事件 API 与 $listeners/$children;EventBus 改用 mitt,父子通信改用 props/emit |
| medium | functional: true 函数式组件 | 1 | ×2 | 改成普通函数组件(props/emits 显式声明),Vue 3 中函数式组件是纯函数 |
| medium | Webpack / vue-cli 强耦合写法 | 6 | ×1 | Rspack 兼容大部分 loader 链,但 require.context 的写法、chainWebpack 配置要重写 |
| medium | mixins 引用 | 9 | ×1.5 | mixins 在 Vue 3 仍可用但同样导致数据来源不透明;建议迁移期换成组合式函数(composables) |
| 文件 | 命中 | |
|---|---|---|
src\views\table\complex-table.vue | 17 | |
src\views\example\list.vue | 10 | |
src\views\table\drag-table.vue | 9 | |
src\views\tab\components\TabPane.vue | 8 | |
src\views\table\inline-edit-table.vue | 8 | |
src\views\components-demo\mixin.vue | 6 | |
src\views\dashboard\admin\components\TransactionTable.vue | 6 | |
src\views\excel\export-excel.vue | 5 | |
src\views\excel\merge-header.vue | 5 | |
src\views\excel\select-excel.vue | 5 | |
src\views\permission\role.vue | 5 | |
src\views\zip\index.vue | 5 | |
src\components\ErrorLog\index.vue | 4 | |
src\views\components-demo\split-pane.vue | 4 | |
src\main.js | 3 |
| 包 | 当前版本 | 处置 |
|---|---|---|
echarts | 4.2.1 | echarts 4 及以下 —— 5.x API 有破坏性变更 |
element-ui | 2.13.2 | Vue 2 生态 UI 库 —— 需换 element-plus / vant 4 |
vue | 2.6.10 | Vue 2 —— 迁移主体,升到 3.x |
vue-router | 3.0.2 | Vue Router 2/3 —— 升到 4/5,API 从 new Router() 改为 createRouter() |
vuex | 3.1.0 | Vuex 3 —— 官方推荐迁移到 Pinia |
@vue/cli-service | 4.4.4 | vue-cli —— 换 Rspack/Vite 构建 |
| 包 | 当前版本 | 说明 |
|---|---|---|
element-ui | 2.13.2 | Vue 2 生态 UI 库 —— 需换 element-plus / vant 4 / view-ui-plus |
vuedraggable | 2.20.0 | vuedraggable 2 —— Vue 3 需换 vuedraggable@next 或 vue-draggable-plus |
vuex | 3.1.0 | Vuex 3 —— Vue 3 里能跑但官方推荐 Pinia;this.$store 在 setup 中不可用 |
src\components\BackToTop\index.vue:50beforeDestroy() {src\components\Charts\Keyboard.vue:37beforeDestroy() {src\components\Charts\LineMarker.vue:37beforeDestroy() {src\components\Charts\MixChart.vue:37beforeDestroy() {src\components\Charts\mixins\resize.js:22beforeDestroy() {src\components\Dropzone\index.vue:167destroyed() {src\components\ImageCropper\index.vue:403destroyed() {src\components\MarkdownEditor\index.vue:83destroyed() {src\components\RightPanel\index.vue:55beforeDestroy() {src\components\Screenfull\index.vue:20beforeDestroy() {src\components\Sticky\index.vue:48destroyed() {src\components\Tinymce\index.vue:101destroyed() {src\layout\components\TagsView\ScrollPane.vue:25beforeDestroy() {src\layout\mixin\ResizeHandler.js:17beforeDestroy() {src\views\dashboard\admin\components\BarChart.vue:38beforeDestroy() {src\views\dashboard\admin\components\LineChart.vue:52beforeDestroy() {src\views\dashboard\admin\components\mixins\resize.js:19beforeDestroy() {src\views\dashboard\admin\components\PieChart.vue:36beforeDestroy() {src\views\dashboard\admin\components\RaddarChart.vue:38beforeDestroy() {src\views\login\index.vue:137destroyed() {src\components\ErrorLog\index.vue:9<el-dialog :visible.sync="dialogTableVisible" width="80%" append-to-body>src\components\Pagination\index.vue:5:current-page.sync="currentPage"src\components\Pagination\index.vue:6:page-size.sync="pageSize"src\components\Tinymce\components\EditorImage.vue:6<el-dialog :visible.sync="dialogVisible">src\views\components-demo\drag-dialog.vue:6<el-dialog v-el-drag-dialog :visible.sync="dialogTableVisible" title="Shipping address" @dragDialog="handleDrag">src\views\error-page\401.vue:31<el-dialog :visible.sync="dialogVisible" title="随便看">src\views\example\list.vue:55<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getLisrc\views\example\list.vue:55<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getLisrc\views\login\index.vue:66<el-dialog title="Or connect with" :visible.sync="showDialog">src\views\permission\role.vue:29<el-dialog :visible.sync="dialogVisible" :title="dialogType==='edit'?'Edit Role':'New Role'">src\views\table\complex-table.vue:100<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getLisrc\views\table\complex-table.vue:100<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getLisrc\views\table\complex-table.vue:102<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">src\views\table\complex-table.vue:137<el-dialog :visible.sync="dialogPvVisible" title="Reading statistics">src\components\ErrorLog\index.vue:10<div slot="title">src\components\ErrorLog\index.vue:16<template slot-scope="{row}">src\components\ErrorLog\index.vue:40<template slot-scope="scope">src\components\SizeSelect\index.vue:6<el-dropdown-menu slot="dropdown">src\layout\components\Navbar.vue:26<el-dropdown-menu slot="dropdown">src\layout\components\Sidebar\Item.vue:28vnodes.push(<span slot='title'>{(title)}</span>)src\layout\components\Sidebar\SidebarItem.vue:12<template slot="title">src\views\components-demo\mixin.vue:5<div slot="header" class="clearfix">src\views\components-demo\mixin.vue:46<div slot="header" class="clearfix">src\views\components-demo\mixin.vue:63<div slot="header" class="clearfix">src\views\components-demo\mixin.vue:76<div slot="header" class="clearfix">src\views\components-demo\mixin.vue:89<div slot="header" class="clearfix">src\views\components-demo\mixin.vue:102<div slot="header" class="clearfix">src\views\components-demo\split-pane.vue:9<template slot="paneL">src\views\components-demo\split-pane.vue:12<template slot="paneR">src\views\components-demo\split-pane.vue:14<template slot="paneL">src\views\components-demo\split-pane.vue:17<template slot="paneR">src\views\components-demo\sticky.vue:8<el-dropdown-menu slot="dropdown" class="no-border">src\views\components-demo\sticky.vue:21<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:300px">src\views\components-demo\sticky.vue:23<template slot="prepend">src\views\dashboard\admin\components\BoxCard.vue:3<div slot="header" class="box-card-header">src\views\dashboard\admin\components\TransactionTable.vue:4<template slot-scope="scope">src\views\dashboard\admin\components\TransactionTable.vue:9<template slot-scope="scope">src\views\dashboard\admin\components\TransactionTable.vue:14<template slot-scope="{row}">src\views\example\components\Dropdown\Comment.vue:7<el-dropdown-menu slot="dropdown" class="no-padding">src\views\example\components\Dropdown\Platform.vue:7<el-dropdown-menu slot="dropdown" class="no-border">src\views\example\components\Dropdown\SourceUrl.vue:7<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px">src\views\example\components\Dropdown\SourceUrl.vue:10<template slot="prepend">src\views\example\list.vue:5<template slot-scope="scope">src\views\example\list.vue:11<template slot-scope="scope">src\views\example\list.vue:17<template slot-scope="scope">src\views\example\list.vue:23<template slot-scope="scope">src\views\example\list.vue:29<template slot-scope="{row}">src\views\example\list.vue:37<template slot-scope="{row}">src\views\example\list.vue:45<template slot-scope="scope">src\views\excel\export-excel.vue:18<template slot-scope="scope">src\views\excel\export-excel.vue:23<template slot-scope="scope">src\views\excel\export-excel.vue:28<template slot-scope="scope">src\views\excel\export-excel.vue:33<template slot-scope="scope">src\views\excel\export-excel.vue:38<template slot-scope="scope">src\views\excel\merge-header.vue:16<template slot-scope="scope">src\views\excel\merge-header.vue:22<template slot-scope="scope">src\views\excel\merge-header.vue:27<template slot-scope="scope">src\views\excel\merge-header.vue:32<template slot-scope="scope">src\views\excel\merge-header.vue:38<template slot-scope="scope">src\views\excel\select-excel.vue:22<template slot-scope="scope">src\views\excel\select-excel.vue:27<template slot-scope="scope">src\views\excel\select-excel.vue:32<template slot-scope="scope">src\views\excel\select-excel.vue:37<template slot-scope="scope">src\views\excel\select-excel.vue:42<template slot-scope="scope">src\views\icons\index.vue:12<div slot="content">src\views\icons\index.vue:27<div slot="content">src\views\permission\role.vue:7<template slot-scope="scope">src\views\permission\role.vue:12<template slot-scope="scope">src\views\permission\role.vue:17<template slot-scope="scope">src\views\permission\role.vue:22<template slot-scope="scope">src\views\profile\components\UserCard.vue:3<div slot="header" class="clearfix">src\views\tab\components\TabPane.vue:10<template slot-scope="scope">src\views\tab\components\TabPane.vue:16<template slot-scope="scope">src\views\tab\components\TabPane.vue:22<template slot-scope="{row}">src\views\tab\components\TabPane.vue:29<template slot-scope="scope">src\views\tab\components\TabPane.vue:35<template slot-scope="scope">src\views\tab\components\TabPane.vue:41<template slot-scope="scope">src\views\tab\components\TabPane.vue:47<template slot-scope="{row}">src\views\table\complex-table.vue:39<template slot-scope="{row}">src\views\table\complex-table.vue:44<template slot-scope="{row}">src\views\table\complex-table.vue:49<template slot-scope="{row}">src\views\table\complex-table.vue:55<template slot-scope="{row}">src\views\table\complex-table.vue:60<template slot-scope="{row}">src\views\table\complex-table.vue:65<template slot-scope="{row}">src\views\table\complex-table.vue:70<template slot-scope="{row}">src\views\table\complex-table.vue:76<template slot-scope="{row}">src\views\table\complex-table.vue:83<template slot-scope="{row,$index}">src\views\table\complex-table.vue:127<div slot="footer" class="dialog-footer">src\views\table\complex-table.vue:142<span slot="footer" class="dialog-footer">src\views\table\drag-table.vue:6<template slot-scope="{row}">src\views\table\drag-table.vue:12<template slot-scope="{row}">src\views\table\drag-table.vue:18<template slot-scope="{row}">src\views\table\drag-table.vue:24<template slot-scope="{row}">src\views\table\drag-table.vue:30<template slot-scope="{row}">src\views\table\drag-table.vue:36<template slot-scope="{row}">src\views\table\drag-table.vue:42<template slot-scope="{row}">src\views\table\drag-table.vue:50<template slot-scope="{}">src\views\table\dynamic-table\components\FixedThead.vue:20<template slot-scope="scope">src\views\table\dynamic-table\components\UnfixedThead.vue:20<template slot-scope="scope">src\views\table\inline-edit-table.vue:5<template slot-scope="{row}">src\views\table\inline-edit-table.vue:11<template slot-scope="{row}">src\views\table\inline-edit-table.vue:17<template slot-scope="{row}">src\views\table\inline-edit-table.vue:23<template slot-scope="{row}">src\views\table\inline-edit-table.vue:29<template slot-scope="{row}">src\views\table\inline-edit-table.vue:37<template slot-scope="{row}">src\views\table\inline-edit-table.vue:55<template slot-scope="{row}">src\views\theme\index.vue:4<div slot="header">src\views\zip\index.vue:9<template slot-scope="scope">src\views\zip\index.vue:14<template slot-scope="scope">src\views\zip\index.vue:19<template slot-scope="scope">src\views\zip\index.vue:24<template slot-scope="scope">src\views\zip\index.vue:29<template slot-scope="scope">src\views\dashboard\admin\components\BoxCard.vue:37filters: {src\views\dashboard\admin\components\TodoList\index.vue:26{{ remaining | pluralize('item') }} leftsrc\views\dashboard\admin\components\TodoList\index.vue:30<a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a>src\views\dashboard\admin\components\TodoList\index.vue:61filters: {src\views\dashboard\admin\components\TransactionTable.vue:5{{ scope.row.order_no | orderNoFilter }}src\views\dashboard\admin\components\TransactionTable.vue:10¥{{ scope.row.price | toThousandFilter }}src\views\dashboard\admin\components\TransactionTable.vue:27filters: {src\views\example\list.vue:66filters: {src\views\profile\components\UserCard.vue:16<div class="user-role text-center text-muted">{{ user.role | uppercaseFirst }}</div>src\views\tab\components\TabPane.vue:60filters: {src\views\table\complex-table.vue:51<el-tag>{{ row.type | typeFilter }}</el-tag>src\views\table\complex-table.vue:172filters: {src\views\table\drag-table.vue:70filters: {src\views\table\inline-edit-table.vue:85filters: {src\directive\clipboard\index.js:4Vue.directive('Clipboard', Clipboard)src\directive\clipboard\index.js:9Vue.use(install); // eslint-disable-linesrc\directive\el-drag-dialog\index.js:4Vue.directive('el-drag-dialog', drag)src\directive\el-drag-dialog\index.js:9Vue.use(install); // eslint-disable-linesrc\directive\el-table\index.js:4Vue.directive('el-height-adaptive-table', adaptive)src\directive\el-table\index.js:9Vue.use(install); // eslint-disable-linesrc\directive\permission\index.js:4Vue.directive('permission', permission)src\directive\permission\index.js:9Vue.use(install); // eslint-disable-linesrc\directive\sticky.js:4Vue.directive('sticky', {src\directive\waves\index.js:4Vue.directive('waves', waves)src\directive\waves\index.js:9Vue.use(install); // eslint-disable-linesrc\icons\index.js:5Vue.component('svg-icon', SvgIcon)src\main.js:36Vue.use(Element, {src\main.js:43Vue.filter(key, filters[key])src\main.js:48new Vue({src\router\index.js:4Vue.use(Router)src\store\index.js:5Vue.use(Vuex)src\utils\clipboard.js:5Vue.prototype.$message({src\utils\clipboard.js:13Vue.prototype.$message({src\components\DragSelect\index.vue:2<el-select ref="dragSelect" v-model="selectVal" v-bind="$attrs" class="drag-select" multiple v-on="$listeners">src\components\SvgIcon\index.vue:2<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />src\components\SvgIcon\index.vue:3<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">tests\unit\components\Hamburger.spec.js:7wrapper.vm.$on('toggleClick', mockFn)src\layout\components\Sidebar\Item.vue:4functional: true,mock\mock-server.js:37url: new RegExp(`${process.env.VUE_APP_BASE_API}${url}`),src\icons\index.js:7const req = require.context('./svg', false, /\.svg$/)src\store\index.js:8const modulesFiles = require.context('./modules', true, /\.js$/)src\utils\request.js:8baseURL: process.env.VUE_APP_BASE_API, // url = base url + request urlsrc\views\icons\svg-icons.js:1const req = require.context('../../icons/svg', false, /\.svg$/)vue.config.js:51chainWebpack(config) {src\components\Charts\Keyboard.vue:10mixins: [resize],src\components\Charts\LineMarker.vue:10mixins: [resize],src\components\Charts\MixChart.vue:10mixins: [resize],src\layout\components\Sidebar\SidebarItem.vue:37mixins: [FixiOSBug],src\layout\index.vue:34mixins: [ResizeMixin],src\views\dashboard\admin\components\BarChart.vue:13mixins: [resize],src\views\dashboard\admin\components\LineChart.vue:11mixins: [resize],src\views\dashboard\admin\components\PieChart.vue:11mixins: [resize],src\views\dashboard\admin\components\RaddarChart.vue:13mixins: [resize],