目录
一、安装包相关升级
二、vite.config
三、 入口文件修改
四、App.vue 及相关升级
五、路由
六、状态管理VUEX
一、安装包相关升级
升级pakage.json相关安装包
vue2插件 | vue3替换插件 | vue2使用 | vue3使用 |
vue-ls | vuex-persistedstate或vuex-persist | Vue.ls.get() Vue.ls.set() | 直接操作store相关 |
k-form-design | k-designer | ||
vue-contextmenu | 可使用ui组件 | <vue-context-menu :contextMenuData="[]" @deleteLink="deleteLink"> </vue-context-menu | <a-dropdown :trigger="['contextmenu']"> |
vcolorpicker | 可使用ui组件 | ||
@jiaminghi/data-view | echarts | ||
vue-json-viewer | vue3-json-viewer | ||
vue-draggable | vue-draggable-next | ||
moment | dayjs | ||
升级nodejs15版本及以上
1.安装vite
npm i vite -g
npm create vite@latest
#相关目录文件,注意:vue-cli生成index.html在public下要改为根目录
.package.json
删除vue-cli相关,修改
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
为
{
"name": "vue-antd-pro",
"version": "2.1.0",
"private": true,
"scripts": {
"dev": "vite --mode development",
"build": "vite build",
"serve": "vite preview",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore --fix src",
"test:unit": "vue-cli-service test:unit",
"build:preview": "vue-cli-service build --mode preview",
"postinstall": "opencollective-postinstall"
},
"dependencies": {
"@aspnet/signalr": "^1.0.27",
"@microsoft/signalr": "^7.0.5",
"@rollup/plugin-inject": "^5.0.3",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"@vue/compat": "^3.3.4",
"@vueuse/core": "^6.7.3",
"ant-design-vue": "^4.0.0-rc.4",
"axios": "^1.4.0",
"babel-plugin-transform-remove-strict-mode": "0.0.2",
"babel-polyfill": "^6.26.0",
"echarts": "^5.4.2",
"eslint": "^8.40.0",
"eslint-plugin-vue": "^9.13.0",
"jquery": "^3.5.1",
"jquery-ui": "1.13.0",
"k-designer": "^0.0.42",
"md5": "^2.2.1",
"mockjs2": "1.0.8",
"nprogress": "^0.2.0",
"vite": "^4.3.9",
"vite-plugin-svg-icons": "^2.0.1",
"vue": "^3.3.4",
"vue-clipboard2": "^0.2.1",
"vue-codemirror-lite": "^1.0.4",
"vue-cropper": "^0.5.11",
"vue-draggable-next": "^2.1.1",
"vue-qr": "^4.0.9",
"vue-quill-editor": "^3.0.6",
"vue-router": "^4.2.0",
"vue3-json-viewer": "^2.2.2",
"vuex": "^4.1.0",
"vuex-persistedstate": "^4.1.0",
"wangeditor": "^4.7.15",
},
"devDependencies": {
"@ant-design/colors": "^3.2.1",
"@typescript-eslint/eslint-plugin": "^5.59.6",
"@typescript-eslint/parser": "^5.59.6",
"@vitejs/plugin-vue": "^1.6.1",
"@vitejs/plugin-vue-jsx": "^3.0.1",
"@vitejs/plugin-vue2": "^2.2.0",
"@vue/compiler-sfc": "^3.3.4",
"@vue/eslint-config-prettier": "^7.1.0",
"@vue/eslint-config-standard": "^8.0.1",
"@vue/test-utils": "^2.3.2",
"@zougt/some-loader-utils": "^1.4.3",
"@zougt/vite-plugin-theme-preprocessor": "^1.4.8",
"autoprefixer": "^10.4.14",
"babel-plugin-import": "^1.13.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"eslint": "^8.40.0",
"eslint-config-prettier": "^8.8.0",
"eslint-plugin-html": "^5.0.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.13.0",
"less": "^3.0.4",
"less-loader": "^5.0.0",
"postcss": "^8.4.23",
"postcss-loader": "^7.3.0",
"prettier": "^2.8.8",
"sass": "1.32.0",
"stylus": "^0.54.8",
"unplugin-vue-components": "^0.24.1",
"vite": "^4.3.8",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-require": "^1.1.10",
"vite-plugin-theme": "^0.8.6",
"vue-eslint-parser": "^9.3.0"
},
"main": ".eslintrc.js",
"directories": {
"test": "tests"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
二、vite.config
const path = require("path");
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vitePluginRequire from 'vite-plugin-require';
import inject from '@rollup/plugin-inject';
import Components from 'unplugin-vue-components/vite'
import { AntDesignVueResolver } from 'unplugin-vue-components/resolvers'
import viteCompression from "vite-plugin-compression";
import vueJsx from '@vitejs/plugin-vue-jsx'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
export default defineConfig({
// base: './', // 开发或生产环境服务的公共基础路径径
envDir: './env',
plugins: [
vue({
template: {
compilerOptions: {
compatConfig: {
MODE: 3 // vue2还是vue3模式
}
}
}
}),
vueJsx(),
vitePluginRequire(),
inject({
$: "jquery", // 这里会自动载入 node_modules 中的 jquery jquery全局变量
jQuery: "jquery",
"windows.jQuery": "jquery"
}),
createSvgIconsPlugin({
// 要缓存的图标文件夹
iconDirs: [path.resolve(__dirname, 'src/assets/icons')],
// 执行 icon name 的格式
symbolId: 'icon-[name]'
}),
Components({
dts: 'src/types/components.d.ts',
include: [/\.vue$/, /\.tsx$/],
resolvers: [ AntDesignVueResolver({
// 参数配置可参考:https://github.com/antfu/unplugin-vue-components/blob/main/src/core/resolvers/antdv.ts
// 自动引入 ant-design/icons-vue中的图标,需要安装@ant-design/icons-vue
// importStyle: 'less',
importStyle: false,
resolveIcons: true,
})]
}),
viteCompression() // gzip
],
// publicDir: 'public',
cacheDir: 'node_modules/.vite',
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
'vue': 'vue/dist/vue.esm-bundler.js',
// vue: '@vue/compat',
},
extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'], // 忽略文件后缀
},
css: {
preprocessorOptions: {
less: {
javascriptEnabled: true
}
}
},
// 服务的配置
server: {
cors: false,
// 主机名
host: '0.0.0.0',
// 端口
port: 8080,
// 端口被占用调用下个端口
strictPort: false,
// boolean | String 如果是boolean且为true 会自动打开浏览器。 配置是字符串 会被用作 URL 的路径名
open: false,
/*
服务器代理地址,用于代理到后台的服务器。
*/
// proxy: createProxy(),
// force: true // 强制使依赖预构建。
//
fs: {
strict: false
}
},
// 正式环境的配置
build: {
// 去除console debug
terserOptions: {
compress: {
drop_console: true,
drop_debugger: true
}
},
target: 'modules',
// target: 'es2015',
// 指定输出的路径,相当于项目根目录
// outDir: mode.includes('production.hr') ? 'dist/hr' : 'dist/uc',
// 静态资源存放路径,相对于outDir
// assetsDir: 'public/',
// 小于此配置的会被base64编码,0为完全禁用
assetsInlineLimit: 4096,
// 启用/禁用css代码拆分 如果禁用整个项目所有css将会提取为一个css
cssCodeSplit: true,
// boolean| inline 构建后是不是生产source map 文件
sourcemap: false,
// 启用和禁用压缩报告
brotliSize: true,
// chunk大小警告
// chunkSizeWarningLimit: 500,
minify: true, //打包结果取消minify,方便我们看打包后结果对比 'terser'
chunkSizeWarningLimit: 500,
rollupOptions: {
// input: resolve(__dirname, 'index.html'),
output: {
chunkFileNames: 'static/js/[name]-[hash].js',
entryFileNames: 'static/js/[name]-[hash].js',
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
manualChunks(id) {
if (id.includes('node_modules')) {
return 'vendor';
}
},
brotliSize: false, // 不统计
target: 'esnext',
minify: 'esbuild' // 混淆器,terser构建后文件体积更小
},
},
}})
三、 入口文件修改
index.html ,全局main.js引入
<script type="module" src="./src/main.js"></script>
main.js
根据项目已有插件进行升级,注意app创建实例已修改,以下为参考
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from '@/store/index';
import { Modal, message, notification } from 'ant-design-vue'
import { VueAxios } from './utils/request'
import '@/components/flow/style/flow-designer.scss'
import './components/global.less'
import '@/components/index.less'
import './permission.js' // permission control
import './utils/filter' // global filter
import 'regenerator-runtime/runtime'
import 'core-js/stable'
import socket from './utils/socket'
import { sysApplication } from './utils/applocation'
import { hasBtnPermission } from './utils/permissions' // button permission
import dictionary from './utils/dictionary'
// 引入k-designer表单设计器相关,该设计器适用于antdv3版本
// import 'ant-design-vue/dist/reset.css';
import "k-designer/dist/style.css";
setupAntd(pluginManager);
import { pluginManager } from "k-designer";
import { setupAntd } from "k-designer/dist/ui/antd";
setupAntd(pluginManager);
import * as echarts from 'echarts'
const app = createApp(App)
// 代替Vue2 Vue.use
app.use(router)
app.use(store)
app.use(socket, '/hubs/chatHub')
// 全局注册图标组件
import 'virtual:svg-icons-register'
import * as Icons from '@ant-design/icons-vue'
Object.keys(Icons).map(key => {
app.component(key, Icons[key])
})
// 代替Vue2 Vue.prototype
app.config.globalProperties.$confirm = Modal.confirm
app.config.globalProperties.$message = message
app.config.globalProperties.$notification = notification
app.config.globalProperties.$info = Modal.info
app.config.globalProperties.$success = Modal.success
app.config.globalProperties.$error = Modal.error
app.config.globalProperties.$warning = Modal.warning
app.config.globalProperties.VueAxios = VueAxios;
app.config.globalProperties.hasPerm = hasBtnPermission;
app.config.globalProperties.applocation = sysApplication;
app.config.globalProperties.dic = dictionary;
app.config.globalProperties.$echarts = echarts;
app.mount('#app')
四、App.vue 及相关<router-view>升级
<router-view class="page" v-slot="{ Component }">
<transition name="route" mode="out-in">
<component :is="Component"></component>
</transition>
</router-view>
<router-view class="page" v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
五、路由
npm install vue-router@4
import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router'
import { constantRouterMap } from '@/config/router.config'
import '@/components/NProgress/nprogress.less' // progress bar custom style
const router = createRouter({
history: createWebHistory(), // history模式 createWebHashHistory hash模式
base: import.meta.env.VITE_APP_API_BASE_URL,
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap // 路由表
})
// 前增加下面代码,添加一个临时路由
console.log(router.hasRoute(), window.location.pathname)
// if (!router.hasRoute()) {
// router.addRoute({
// path: window.location.pathname,
// name: 'TempRoute',
// component: () => import('@/views/system/exception/404.vue')
// })
// }
export default router
六、状态管理VUEX
npm install vuex@next
import { createStore } from 'vuex';
import createPersistedState from 'vuex-persistedstate' // 持久化state, 代替vue-ls相关
export default createStore({ // 替代之前的 new Vuex.Store()
state: {
},
mutations: {
},
actions: {
},
plugins: [
createPersistedState({
storage: window.localStorage //可为window.sessionstorage
})]
});