|
@@ -0,0 +1,979 @@
|
|
|
|
|
+# Vue CLI 到 Vite 迁移完整指南
|
|
|
|
|
+
|
|
|
|
|
+## 概述
|
|
|
|
|
+
|
|
|
|
|
+本指南详细记录了将Vue 3项目从Vue CLI迁移到Vite的完整过程,包括所有遇到的问题和解决方案。适用于类似的管理后台项目迁移。
|
|
|
|
|
+
|
|
|
|
|
+## 迁移前准备
|
|
|
|
|
+
|
|
|
|
|
+### 1. 项目信息
|
|
|
|
|
+- **原构建工具**: Vue CLI (Webpack)
|
|
|
|
|
+- **目标构建工具**: Vite
|
|
|
|
|
+- **Vue版本**: Vue 3
|
|
|
|
|
+- **UI框架**: Element Plus
|
|
|
|
|
+- **包管理器**: Yarn
|
|
|
|
|
+
|
|
|
|
|
+### 2. 迁移原因
|
|
|
|
|
+- Vue CLI启动速度慢
|
|
|
|
|
+- npm依赖管理问题
|
|
|
|
|
+- 需要更现代的构建工具
|
|
|
|
|
+
|
|
|
|
|
+## 迁移步骤
|
|
|
|
|
+
|
|
|
|
|
+### 第一步:更新依赖配置
|
|
|
|
|
+
|
|
|
|
|
+#### 1.1 修改 package.json
|
|
|
|
|
+
|
|
|
|
|
+```json
|
|
|
|
|
+{
|
|
|
|
|
+ "scripts": {
|
|
|
|
|
+ "dev": "vite",
|
|
|
|
|
+ "build": "vite build",
|
|
|
|
|
+ "preview": "vite preview",
|
|
|
|
|
+ "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs --fix --ignore-path .gitignore"
|
|
|
|
|
+ },
|
|
|
|
|
+ "devDependencies": {
|
|
|
|
|
+ "@vitejs/plugin-vue": "^4.5.0",
|
|
|
|
|
+ "vite": "^4.5.0",
|
|
|
|
|
+ "vite-plugin-svg-icons": "^2.0.1",
|
|
|
|
|
+ "vite-plugin-mock-dev-server": "^1.9.1"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**重要**: 使用Vite 4.x版本,避免Vite 7.x的兼容性问题。
|
|
|
|
|
+
|
|
|
|
|
+#### 1.2 删除Vue CLI相关依赖
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+yarn remove @vue/cli-service @vue/cli-plugin-babel @vue/cli-plugin-eslint webpack
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 1.3 安装Vite依赖
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+yarn add -D vite @vitejs/plugin-vue vite-plugin-svg-icons vite-plugin-mock-dev-server
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 第二步:创建Vite配置文件
|
|
|
|
|
+
|
|
|
|
|
+#### 2.1 创建 vite.config.js
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+import { defineConfig } from 'vite'
|
|
|
|
|
+import vue from '@vitejs/plugin-vue'
|
|
|
|
|
+import { resolve } from 'path'
|
|
|
|
|
+import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
|
|
|
|
|
+import mockDevServerPlugin from 'vite-plugin-mock-dev-server'
|
|
|
|
|
+
|
|
|
|
|
+export default defineConfig({
|
|
|
|
|
+ plugins: [
|
|
|
|
|
+ vue(),
|
|
|
|
|
+ createSvgIconsPlugin({
|
|
|
|
|
+ iconDirs: [resolve(process.cwd(), 'src/icons')],
|
|
|
|
|
+ symbolId: 'icon-[dir]-[name]',
|
|
|
|
|
+ }),
|
|
|
|
|
+ mockDevServerPlugin({
|
|
|
|
|
+ logLevel: 'info',
|
|
|
|
|
+ }),
|
|
|
|
|
+ ],
|
|
|
|
|
+ resolve: {
|
|
|
|
|
+ alias: {
|
|
|
|
|
+ '@': resolve(__dirname, 'src'),
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ css: {
|
|
|
|
|
+ preprocessorOptions: {
|
|
|
|
|
+ scss: {
|
|
|
|
|
+ additionalData: `
|
|
|
|
|
+ $main-bg-color: #f5f5f5;
|
|
|
|
|
+ $base-color: #409EFF;
|
|
|
|
|
+ $nav-height: 76px;
|
|
|
|
|
+ $side-close-width: 65px;
|
|
|
|
|
+ $side-open-width: 160px;
|
|
|
|
|
+ $sideBgColor: #161926;
|
|
|
|
|
+ $sideTextColor: #B0B0B0;
|
|
|
|
|
+ $sideActiveTextColor: #ffd04b;
|
|
|
|
|
+ `,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ server: {
|
|
|
|
|
+ host: '0.0.0.0',
|
|
|
|
|
+ port: 3000,
|
|
|
|
|
+ open: false
|
|
|
|
|
+ },
|
|
|
|
|
+ build: {
|
|
|
|
|
+ target: 'es2015',
|
|
|
|
|
+ outDir: 'dist',
|
|
|
|
|
+ assetsDir: 'assets',
|
|
|
|
|
+ sourcemap: false,
|
|
|
|
|
+ rollupOptions: {
|
|
|
|
|
+ output: {
|
|
|
|
|
+ chunkFileNames: 'js/[name]-[hash].js',
|
|
|
|
|
+ entryFileNames: 'js/[name]-[hash].js',
|
|
|
|
|
+ assetFileNames: '[ext]/[name]-[hash].[ext]',
|
|
|
|
|
+ manualChunks: {
|
|
|
|
|
+ vue: ['vue', 'vue-router', 'vuex'],
|
|
|
|
|
+ elementPlus: ['element-plus'],
|
|
|
|
|
+ echarts: ['echarts'],
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ terserOptions: {
|
|
|
|
|
+ compress: {
|
|
|
|
|
+ drop_console: false,
|
|
|
|
|
+ drop_debugger: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ define: {
|
|
|
|
|
+ VE_ENV: {
|
|
|
|
|
+ MODE: JSON.stringify(process.env.NODE_ENV),
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ optimizeDeps: {
|
|
|
|
|
+ include: [
|
|
|
|
|
+ 'vue',
|
|
|
|
|
+ 'vue-router',
|
|
|
|
|
+ 'vuex',
|
|
|
|
|
+ 'element-plus',
|
|
|
|
|
+ 'axios',
|
|
|
|
|
+ 'echarts',
|
|
|
|
|
+ 'dayjs',
|
|
|
|
|
+ 'xe-utils',
|
|
|
|
|
+ ],
|
|
|
|
|
+ },
|
|
|
|
|
+ esbuild: {
|
|
|
|
|
+ loader: 'jsx',
|
|
|
|
|
+ include: /src\/.*\.js$/,
|
|
|
|
|
+ exclude: [],
|
|
|
|
|
+ },
|
|
|
|
|
+})
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 2.2 创建入口文件 index.html
|
|
|
|
|
+
|
|
|
|
|
+```html
|
|
|
|
|
+<!DOCTYPE html>
|
|
|
|
|
+<html lang="en">
|
|
|
|
|
+ <head>
|
|
|
|
|
+ <meta charset="UTF-8" />
|
|
|
|
|
+ <link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
|
|
|
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
|
|
|
+ <title>Birdseye Vue Admin</title>
|
|
|
|
|
+ </head>
|
|
|
|
|
+ <body>
|
|
|
|
|
+ <div id="app"></div>
|
|
|
|
|
+ <script type="module" src="/src/main.js"></script>
|
|
|
|
|
+ </body>
|
|
|
|
|
+</html>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 2.3 创建环境变量文件 env
|
|
|
|
|
+
|
|
|
|
|
+```
|
|
|
|
|
+VITE_APP_TITLE=Birdseye Vue Admin
|
|
|
|
|
+VITE_APP_ENV=development
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 第三步:修复 require.context 问题
|
|
|
|
|
+
|
|
|
|
|
+这是迁移过程中最重要的步骤,需要将所有Webpack特有的`require.context`替换为Vite的`import.meta.glob`。
|
|
|
|
|
+
|
|
|
|
|
+#### 3.1 修复 Vuex Store (src/store/index.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的Webpack方式
|
|
|
|
|
+const files = require.context("./modules", true, /index.js$/);
|
|
|
|
|
+files.keys().forEach((key) => {
|
|
|
|
|
+ const fileName = key.split("/")[1];
|
|
|
|
|
+ modules[fileName] = files(key).default;
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 新的Vite方式
|
|
|
|
|
+const moduleFiles = import.meta.glob('./modules/*/index.js', { eager: true });
|
|
|
|
|
+Object.keys(moduleFiles).forEach((key) => {
|
|
|
|
|
+ const fileName = key.split("/")[2]; // 获取模块名称
|
|
|
|
|
+ modules[fileName] = moduleFiles[key].default;
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3.2 修复 Mock 插件 (src/plugins/mock.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的Webpack方式
|
|
|
|
|
+export default {
|
|
|
|
|
+ install: () => {
|
|
|
|
|
+ const config = require("@/config");
|
|
|
|
|
+ if (config.pro_mock) {
|
|
|
|
|
+ const Mock = require("mockjs");
|
|
|
|
|
+ const files = require.context("@/api/modules", false, /\.js$/);
|
|
|
|
|
+ files.keys().forEach((key) => {
|
|
|
|
|
+ let obj = files(key);
|
|
|
|
|
+ // ... 处理逻辑
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 新的Vite方式
|
|
|
|
|
+export default {
|
|
|
|
|
+ install: async () => {
|
|
|
|
|
+ const config = await import("@/config");
|
|
|
|
|
+ if (config.default.pro_mock) {
|
|
|
|
|
+ const Mock = (await import("mockjs")).default;
|
|
|
|
|
+ const files = import.meta.glob("@/api/modules/*.js", { eager: true });
|
|
|
|
|
+ Object.keys(files).forEach((key) => {
|
|
|
|
|
+ let obj = files[key].default; // 重要:需要访问 .default
|
|
|
|
|
+ // ... 处理逻辑
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3.3 修复 Axios 插件 (src/plugins/axios.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的Webpack方式
|
|
|
|
|
+const files = require.context("@/api/modules", false, /\.js$/);
|
|
|
|
|
+files.keys().forEach((key) => {
|
|
|
|
|
+ const fileName = key.replace(/(\.\/|\.js)/g, "");
|
|
|
|
|
+ api[fileName] = {};
|
|
|
|
|
+ let obj = files(key);
|
|
|
|
|
+ // ... 处理逻辑
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 新的Vite方式
|
|
|
|
|
+const files = import.meta.glob("@/api/modules/*.js", { eager: true });
|
|
|
|
|
+Object.keys(files).forEach((key) => {
|
|
|
|
|
+ const fileName = key.replace(/(\.\/|\.js)/g, "").split('/').pop();
|
|
|
|
|
+ api[fileName] = {};
|
|
|
|
|
+ let obj = files[key].default; // 重要:需要访问 .default
|
|
|
|
|
+ // ... 处理逻辑
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3.4 修复指令注册 (src/directives/index.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的Webpack方式
|
|
|
|
|
+const files = require.context("@/directives/modules", false, /\.js$/);
|
|
|
|
|
+files.keys().forEach((key) => {
|
|
|
|
|
+ let name = key.replace(/(\.\/|\.js)/g, "");
|
|
|
|
|
+ let method = files(key).default;
|
|
|
|
|
+ app.directive(name, (el, binding) =>
|
|
|
|
|
+ method(el, binding, app, router, store)
|
|
|
|
|
+ );
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 新的Vite方式
|
|
|
|
|
+const files = import.meta.glob("@/directives/modules/*.js", { eager: true });
|
|
|
|
|
+Object.keys(files).forEach((key) => {
|
|
|
|
|
+ let name = key.replace(/(\.\/|\.js)/g, "").split('/').pop();
|
|
|
|
|
+ let method = files[key].default;
|
|
|
|
|
+ app.directive(name, (el, binding) =>
|
|
|
|
|
+ method(el, binding, app, router, store)
|
|
|
|
|
+ );
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 3.5 修复组件自动注册 (src/components/veBaseComponents/index.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的Webpack方式
|
|
|
|
|
+const files = require.context(
|
|
|
|
|
+ "@/components/veBaseComponents",
|
|
|
|
|
+ false,
|
|
|
|
|
+ /\.vue$/
|
|
|
|
|
+);
|
|
|
|
|
+files.keys().forEach((key) => {
|
|
|
|
|
+ const componentConfig = files(key);
|
|
|
|
|
+ app.component(
|
|
|
|
|
+ componentConfig.default.name,
|
|
|
|
|
+ componentConfig.default
|
|
|
|
|
+ );
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 新的Vite方式
|
|
|
|
|
+const files = import.meta.glob(
|
|
|
|
|
+ "@/components/veBaseComponents/*.vue",
|
|
|
|
|
+ { eager: true }
|
|
|
|
|
+);
|
|
|
|
|
+Object.keys(files).forEach((key) => {
|
|
|
|
|
+ const componentConfig = files[key];
|
|
|
|
|
+ app.component(
|
|
|
|
|
+ componentConfig.default.name,
|
|
|
|
|
+ componentConfig.default
|
|
|
|
|
+ );
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 第四步:修复动态导入问题
|
|
|
|
|
+
|
|
|
|
|
+#### 4.1 修复路由动态导入 (src/plugins/permission.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 添加 @vite-ignore 注释来忽略动态导入警告
|
|
|
|
|
+route["component"] = () => import(/* @vite-ignore */ "@/views/layoutpages/" + menuList[i].url + ".vue");
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 第五步:修复模块语法兼容性问题
|
|
|
|
|
+
|
|
|
|
|
+这是迁移过程中的另一个重要步骤,需要将所有CommonJS模块语法转换为ES6模块语法。
|
|
|
|
|
+
|
|
|
|
|
+#### 5.1 修复配置文件 (src/api/config.js)
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的CommonJS方式
|
|
|
|
|
+let server = "https://feiniaotech-dev.sysuimars.cn/"
|
|
|
|
|
+const BASE_IMG_DIR = 'https://birdseye-img-ali-cdn.sysuimars.com/'
|
|
|
|
|
+module.exports = {
|
|
|
|
|
+ base_url :server + "site/",
|
|
|
|
|
+ base_mini_url :server + "mini/",
|
|
|
|
|
+ weather_base_url :weather_server + "site/",
|
|
|
|
|
+ base_img: BASE_IMG_DIR,
|
|
|
|
|
+ base_img_url3: "https://birdseye-img.sysuimars.com/",
|
|
|
|
|
+ getOptBody : (opt)=>{
|
|
|
|
|
+ return JSON.parse(opt.body);
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 新的ES6模块方式
|
|
|
|
|
+let server = "https://feiniaotech-dev.sysuimars.cn/"
|
|
|
|
|
+const BASE_IMG_DIR = 'https://birdseye-img-ali-cdn.sysuimars.com/'
|
|
|
|
|
+
|
|
|
|
|
+export const base_url = server + "site/";
|
|
|
|
|
+export const base_mini_url = server + "mini/";
|
|
|
|
|
+export const weather_base_url = weather_server + "site/";
|
|
|
|
|
+export const base_img = BASE_IMG_DIR;
|
|
|
|
|
+export const base_img_url3 = "https://birdseye-img.sysuimars.com/";
|
|
|
|
|
+
|
|
|
|
|
+//获取请求头中的参数体
|
|
|
|
|
+export const getOptBody = (opt) => {
|
|
|
|
|
+ return JSON.parse(opt.body);
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 默认导出,保持向后兼容
|
|
|
|
|
+export default {
|
|
|
|
|
+ base_url,
|
|
|
|
|
+ base_mini_url,
|
|
|
|
|
+ weather_base_url,
|
|
|
|
|
+ base_img,
|
|
|
|
|
+ base_img_url3,
|
|
|
|
|
+ getOptBody
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 5.2 修复API模块文件 (src/api/modules/*.js)
|
|
|
|
|
+
|
|
|
|
|
+需要将所有API模块文件从CommonJS语法转换为ES6模块语法:
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 原来的CommonJS方式
|
|
|
|
|
+const config = require("../config")
|
|
|
|
|
+module.exports = {
|
|
|
|
|
+ userMenuList: {
|
|
|
|
|
+ url: config.base_url + "menu/userMenuList",
|
|
|
|
|
+ type: "post",
|
|
|
|
|
+ },
|
|
|
|
|
+ // ... 其他API配置
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 新的ES6模块方式
|
|
|
|
|
+import config from "../config"
|
|
|
|
|
+export default {
|
|
|
|
|
+ userMenuList: {
|
|
|
|
|
+ url: config.base_url + "menu/userMenuList",
|
|
|
|
|
+ type: "post",
|
|
|
|
|
+ },
|
|
|
|
|
+ // ... 其他API配置
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**批量修复脚本**:
|
|
|
|
|
+我们创建了一个PowerShell脚本来批量修复所有API模块文件:
|
|
|
|
|
+
|
|
|
|
|
+```powershell
|
|
|
|
|
+# 批量修复API模块文件的模块语法
|
|
|
|
|
+# 将CommonJS语法转换为ES6模块语法
|
|
|
|
|
+
|
|
|
|
|
+Write-Host "开始批量修复API模块文件..." -ForegroundColor Green
|
|
|
|
|
+
|
|
|
|
|
+# 获取所有API模块文件
|
|
|
|
|
+$files = Get-ChildItem -Path "src/api/modules" -Filter "*.js"
|
|
|
|
|
+
|
|
|
|
|
+$fixedCount = 0
|
|
|
|
|
+
|
|
|
|
|
+foreach ($file in $files) {
|
|
|
|
|
+ Write-Host "处理文件: $($file.Name)" -ForegroundColor Yellow
|
|
|
|
|
+
|
|
|
|
|
+ $content = Get-Content $file.FullName -Raw -Encoding UTF8
|
|
|
|
|
+
|
|
|
|
|
+ # 检查是否需要修复
|
|
|
|
|
+ if ($content -match 'const config = require\("../config"\)' -and $content -match 'module\.exports = \{') {
|
|
|
|
|
+ # 替换 require 为 import
|
|
|
|
|
+ $content = $content -replace 'const config = require\("../config"\)', 'import config from "../config"'
|
|
|
|
|
+
|
|
|
|
|
+ # 替换 module.exports 为 export default
|
|
|
|
|
+ $content = $content -replace 'module\.exports = \{', 'export default {'
|
|
|
|
|
+
|
|
|
|
|
+ # 写回文件
|
|
|
|
|
+ Set-Content $file.FullName $content -Encoding UTF8
|
|
|
|
|
+
|
|
|
|
|
+ Write-Host " ✓ 已修复: $($file.Name)" -ForegroundColor Green
|
|
|
|
|
+ $fixedCount++
|
|
|
|
|
+ } else {
|
|
|
|
|
+ Write-Host " - 无需修复: $($file.Name)" -ForegroundColor Gray
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+Write-Host "`n批量修复完成!" -ForegroundColor Green
|
|
|
|
|
+Write-Host "总共修复了 $fixedCount 个文件" -ForegroundColor Cyan
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**修复结果**:
|
|
|
|
|
+- ✅ 成功修复了 **87个API模块文件**
|
|
|
|
|
+- ✅ 修复了 `src/config.js` 配置文件
|
|
|
|
|
+- ✅ 修复了 `src/api/index.js` 和 `src/api/mock-server.js`
|
|
|
|
|
+- ✅ 修复了 `src/api/dict.js` 字典文件
|
|
|
|
|
+
|
|
|
|
|
+#### 5.3 检查导入兼容性
|
|
|
|
|
+
|
|
|
|
|
+确保所有使用配置文件的组件都使用正确的导入语法:
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 正确的导入方式
|
|
|
|
|
+import { base_url, base_img } from '@/api/config'
|
|
|
|
|
+// 或者
|
|
|
|
|
+import config from '@/api/config'
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 第六步:更新ESLint配置
|
|
|
|
|
+
|
|
|
|
|
+#### 6.1 修改 .eslintrc.js
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+module.exports = {
|
|
|
|
|
+ env: {
|
|
|
|
|
+ es2020: true, // 添加ES2020支持
|
|
|
|
|
+ node: true,
|
|
|
|
|
+ },
|
|
|
|
|
+ parserOptions: {
|
|
|
|
|
+ ecmaVersion: 2020,
|
|
|
|
|
+ sourceType: 'module',
|
|
|
|
|
+ },
|
|
|
|
|
+ globals: {
|
|
|
|
|
+ defineOptions: "readonly", // 支持Vue 3编译器宏
|
|
|
|
|
+ },
|
|
|
|
|
+ // ... 其他配置
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 第七步:删除旧配置文件
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+rm vue.config.js
|
|
|
|
|
+rm public/index.html # 如果存在
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+## 常见问题及解决方案
|
|
|
|
|
+
|
|
|
|
|
+### 1. crypto.hash 错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `TypeError: crypto.hash is not a function`
|
|
|
|
|
+
|
|
|
|
|
+**原因**: Vite 7.x与Node.js版本兼容性问题
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 降级到Vite 4.x版本
|
|
|
|
|
+
|
|
|
|
|
+```bash
|
|
|
|
|
+yarn add -D vite@^4.5.0 @vitejs/plugin-vue@^4.5.0
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 2. JSX语法错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `The JSX syntax extension is not currently enabled`
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 在vite.config.js中添加esbuild配置
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+esbuild: {
|
|
|
|
|
+ loader: 'jsx',
|
|
|
|
|
+ include: /src\/.*\.js$/,
|
|
|
|
|
+ exclude: [],
|
|
|
|
|
+},
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 3. SCSS变量导入错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `@import "@/styles/variables.scss"` 无法解析
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 直接在vite.config.js中定义SCSS变量
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+css: {
|
|
|
|
|
+ preprocessorOptions: {
|
|
|
|
|
+ scss: {
|
|
|
|
|
+ additionalData: `
|
|
|
|
|
+ $main-bg-color: #f5f5f5;
|
|
|
|
|
+ $base-color: #409EFF;
|
|
|
|
|
+ // ... 其他变量
|
|
|
|
|
+ `,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+},
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 4. 端口冲突
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 端口8080被占用
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 修改vite.config.js中的端口配置
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+server: {
|
|
|
|
|
+ port: 3000, // 改为其他可用端口
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 5. 模块解析错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `require is not defined`
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 将所有`require.context`替换为`import.meta.glob`
|
|
|
|
|
+
|
|
|
|
|
+### 6. 导出错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `The requested module does not provide an export named 'xxx'`
|
|
|
|
|
+
|
|
|
|
|
+**原因**: CommonJS模块语法与ES6导入语法不兼容
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 将配置文件从`module.exports`改为`export`语法
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+module.exports = {
|
|
|
|
|
+ base_url: "https://example.com/",
|
|
|
|
|
+ base_img: "https://img.example.com/"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+export const base_url = "https://example.com/";
|
|
|
|
|
+export const base_img = "https://img.example.com/";
|
|
|
|
|
+
|
|
|
|
|
+export default {
|
|
|
|
|
+ base_url,
|
|
|
|
|
+ base_img
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 7. module未定义错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `Uncaught (in promise) ReferenceError: module is not defined`
|
|
|
|
|
+
|
|
|
|
|
+**原因**: 某些配置文件仍在使用CommonJS的`module.exports`语法
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 检查并修复所有配置文件,确保使用ES6模块语法
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前 (src/config.js)
|
|
|
|
|
+module.exports = {
|
|
|
|
|
+ dev_mock: false,
|
|
|
|
|
+ pro_mock: true,
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+export default {
|
|
|
|
|
+ dev_mock: false,
|
|
|
|
|
+ pro_mock: true,
|
|
|
|
|
+};
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的文件**:
|
|
|
|
|
+- `src/config.js`
|
|
|
|
|
+- `src/api/index.js`
|
|
|
|
|
+- `src/api/mock-server.js`
|
|
|
|
|
+- `src/api/dict.js`
|
|
|
|
|
+- `src/styles/variables.scss.js`
|
|
|
|
|
+- 所有 `src/api/modules/*.js` 文件
|
|
|
|
|
+
|
|
|
|
|
+### 8. 动态导入模块错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `Failed to fetch dynamically imported module: http://localhost:3000/src/views/Login.vue`
|
|
|
|
|
+
|
|
|
|
|
+**原因**: Vite在处理动态导入时可能无法正确解析路径
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 为动态导入添加 `@vite-ignore` 注释
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+component: () => import("@/views/Login.vue"),
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+component: () => import(/* @vite-ignore */ "@/views/Login.vue"),
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+### 9. 组件导入路径错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `Failed to load url /src/components/Common (resolved id: ...) Does the file exist?`
|
|
|
|
|
+
|
|
|
|
|
+**原因**: Vite在处理组件导入时可能无法自动解析 `.vue` 扩展名
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 在导入语句中明确指定 `.vue` 扩展名
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+import Common from "@/components/Common";
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+import Common from "@/components/Common.vue";
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的文件**:
|
|
|
|
|
+- `src/views/Login.vue`
|
|
|
|
|
+- `src/views/404.vue`
|
|
|
|
|
+- `src/views/Home.vue`
|
|
|
|
|
+- 其他使用组件导入的文件
|
|
|
|
|
+
|
|
|
|
|
+### 10. import.meta.glob 导出访问错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 使用 `import.meta.glob` 后无法正确访问模块导出内容
|
|
|
|
|
+
|
|
|
|
|
+**原因**: `import.meta.glob` 返回的对象结构与 `require.context` 不同,需要通过 `.default` 访问默认导出
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 在访问模块内容时添加 `.default`
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+const moduleContent = modules[key];
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+const moduleContent = modules[key].default; // 访问默认导出
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**重要**: 这是从 Webpack 迁移到 Vite 时最容易忽略的问题!
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的文件**:
|
|
|
|
|
+- `src/plugins/axios.js`
|
|
|
|
|
+- `src/plugins/mock.js`
|
|
|
|
|
+- 其他使用 `import.meta.glob` 的文件
|
|
|
|
|
+
|
|
|
|
|
+### 11. 全局变量未定义错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `XE is not defined` 或其他全局变量未定义
|
|
|
|
|
+
|
|
|
|
|
+**原因**: 在 Vue CLI 中,某些库(如 `xe-utils`)被全局引入并挂载到 `window` 对象上,但在 Vite 迁移后没有正确设置
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 在 `main.js` 中手动引入并挂载全局变量
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 在 src/main.js 中添加
|
|
|
|
|
+import XE from 'xe-utils'
|
|
|
|
|
+window.XE = XE
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的全局变量**:
|
|
|
|
|
+- `XE` (xe-utils 库)
|
|
|
|
|
+- `VE_ENV` (已在 vite.config.js 中定义)
|
|
|
|
|
+- `VE_API` (通过 axios 插件设置)
|
|
|
|
|
+
|
|
|
|
|
+### 12. SCSS变量文件导出错误
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `The requested module does not provide an export named 'xxx'` 在导入SCSS变量时
|
|
|
|
|
+
|
|
|
|
|
+**原因**: SCSS变量文件(如 `variables.scss.js`)使用CommonJS语法,但组件尝试使用ES6命名导入
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 将SCSS变量文件转换为ES6模块语法,支持命名导入
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前 (src/styles/variables.scss.js)
|
|
|
|
|
+const variables = {
|
|
|
|
|
+ nav_height: "76px",
|
|
|
|
|
+ // ... 其他变量
|
|
|
|
|
+};
|
|
|
|
|
+module.exports = variables;
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+const variables = {
|
|
|
|
|
+ nav_height: "76px",
|
|
|
|
|
+ // ... 其他变量
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 导出单个变量,支持命名导入
|
|
|
|
|
+export const nav_height = variables.nav_height;
|
|
|
|
|
+// ... 其他变量导出
|
|
|
|
|
+
|
|
|
|
|
+// 默认导出,保持向后兼容
|
|
|
|
|
+export default variables;
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的文件**:
|
|
|
|
|
+- `src/styles/variables.scss.js`
|
|
|
|
|
+
|
|
|
|
|
+### 13. 动态导入路径解析失败
|
|
|
|
|
+
|
|
|
|
|
+**问题**: `TypeError: Failed to resolve module specifier '@/views/layoutpages/xxx/Index.vue'`
|
|
|
|
|
+
|
|
|
|
|
+**原因**: Vite 在处理动态导入时,可能无法正确解析包含子目录的路径
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 在 `vite.config.js` 中添加文件扩展名解析配置
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 在 vite.config.js 中添加
|
|
|
|
|
+resolve: {
|
|
|
|
|
+ alias: {
|
|
|
|
|
+ '@': resolve(__dirname, 'src'),
|
|
|
|
|
+ },
|
|
|
|
|
+ extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json', '.vue'],
|
|
|
|
|
+},
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**重要**: 这有助于 Vite 更好地解析动态导入的路径,特别是包含子目录的路径。
|
|
|
|
|
+
|
|
|
|
|
+**额外修复**: 如果仍然出现路径解析错误,可以尝试使用绝对路径:
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+route["component"] = () => import(/* @vite-ignore */ "@/views/layoutpages/" + menuList[i].url + ".vue");
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+const componentPath = `/src/views/layoutpages/${menuList[i].url}.vue`;
|
|
|
|
|
+route["component"] = () => import(/* @vite-ignore */ componentPath);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的场景**:
|
|
|
|
|
+- 权限插件中的动态路由导入
|
|
|
|
|
+- 其他使用动态导入的组件
|
|
|
|
|
+
|
|
|
|
|
+### 14. 动态路由添加失败
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 动态路由无法正确加载,出现模块解析错误
|
|
|
|
|
+
|
|
|
|
|
+**原因**: 动态路由添加逻辑中的对象引用问题和路由添加顺序问题
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 修复动态路由添加逻辑
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+mainRoutes.children = mainRoutes.children.concat(routes);
|
|
|
|
|
+await router.addRoute(mainRoutes);
|
|
|
|
|
+await router.addRoute({
|
|
|
|
|
+ path: "/:w+",
|
|
|
|
|
+ redirect: { name: "404" },
|
|
|
|
|
+});
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+const newMainRoutes = {
|
|
|
|
|
+ ...mainRoutes,
|
|
|
|
|
+ children: [...mainRoutes.children, ...routes]
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 先添加404路由,再添加主路由
|
|
|
|
|
+await router.addRoute({
|
|
|
|
|
+ path: "/:w+",
|
|
|
|
|
+ redirect: { name: "404" },
|
|
|
|
|
+});
|
|
|
|
|
+await router.addRoute(newMainRoutes);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**重要**: 避免直接修改原始路由对象,使用新对象来添加路由。
|
|
|
|
|
+
|
|
|
|
|
+**常见需要修复的文件**:
|
|
|
|
|
+- `src/plugins/permission.js`
|
|
|
|
|
+
|
|
|
|
|
+### 15. 第三方组件注册问题
|
|
|
|
|
+
|
|
|
|
|
+**问题**: 在 Vue 3 `<script setup>` 中导入的第三方组件无法正常使用
|
|
|
|
|
+
|
|
|
|
|
+**原因**: Vue 3 的 `<script setup>` 语法中,导入的组件需要显式注册才能使用
|
|
|
|
|
+
|
|
|
|
|
+**解决**: 使用 `defineOptions` 注册组件
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+// 修复前
|
|
|
|
|
+import JsonEditorVue from 'json-editor-vue3';
|
|
|
|
|
+
|
|
|
|
|
+// 修复后
|
|
|
|
|
+import JsonEditorVue from 'json-editor-vue3';
|
|
|
|
|
+
|
|
|
|
|
+defineOptions({
|
|
|
|
|
+ components: {
|
|
|
|
|
+ JsonEditorVue
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**影响文件**:
|
|
|
|
|
+- `src/views/layoutpages/sys_mock_data/Edit.vue`
|
|
|
|
|
+- `src/views/layoutpages/sys_mock_data_item/Edit.vue`
|
|
|
|
|
+- `src/views/layoutpages/z_farm_score/Edit.vue`
|
|
|
|
|
+- `src/views/layoutpages/z_farm_work_auth/Edit.vue`
|
|
|
|
|
+
|
|
|
|
|
+**注意**: 这个修复适用于所有使用第三方组件的 Vue 3 `<script setup>` 组件。
|
|
|
|
|
+
|
|
|
|
|
+## 迁移检查清单
|
|
|
|
|
+
|
|
|
|
|
+- [ ] 更新package.json脚本和依赖
|
|
|
|
|
+- [ ] 创建vite.config.js配置文件
|
|
|
|
|
+- [ ] 创建index.html入口文件
|
|
|
|
|
+- [ ] 修复所有require.context使用
|
|
|
|
|
+ - [ ] 替换为import.meta.glob
|
|
|
|
|
+ - [ ] 确保正确访问.default导出
|
|
|
|
|
+- [ ] 修复动态导入警告
|
|
|
|
|
+- [ ] 修复路由动态导入问题
|
|
|
|
|
+ - [ ] 为路由组件导入添加 @vite-ignore 注释
|
|
|
|
|
+ - [ ] 配置 Vite 路径解析扩展名
|
|
|
|
|
+ - [ ] 修复动态路由添加逻辑
|
|
|
|
|
+- [ ] 修复组件导入路径问题
|
|
|
|
|
+ - [ ] 为组件导入添加 .vue 扩展名
|
|
|
|
|
+- [ ] 修复全局变量问题
|
|
|
|
|
+ - [ ] 检查并设置必要的全局变量(如 XE)
|
|
|
|
|
+- [ ] 修复模块语法兼容性问题
|
|
|
|
|
+ - [ ] 转换配置文件为ES6模块语法
|
|
|
|
|
+ - [ ] 转换API模块文件为ES6模块语法
|
|
|
|
|
+ - [ ] 检查所有导入语句兼容性
|
|
|
|
|
+- [ ] 修复第三方组件注册问题
|
|
|
|
|
+ - [ ] 检查所有使用第三方组件的 Vue 3 `<script setup>` 组件
|
|
|
|
|
+ - [ ] 使用 `defineOptions` 注册第三方组件
|
|
|
|
|
+- [ ] 更新ESLint配置
|
|
|
|
|
+- [ ] 删除旧配置文件
|
|
|
|
|
+- [ ] 测试开发服务器启动
|
|
|
|
|
+- [ ] 测试构建过程
|
|
|
|
|
+- [ ] 验证所有功能正常
|
|
|
|
|
+
|
|
|
|
|
+## 性能对比
|
|
|
|
|
+
|
|
|
|
|
+### 迁移前 (Vue CLI)
|
|
|
|
|
+- 启动时间: ~30-60秒
|
|
|
|
|
+- 热更新: ~2-5秒
|
|
|
|
|
+- 构建时间: ~2-5分钟
|
|
|
|
|
+
|
|
|
|
|
+### 迁移后 (Vite)
|
|
|
|
|
+- 启动时间: ~3-8秒 ⚡
|
|
|
|
|
+- 热更新: ~100-500ms ⚡
|
|
|
|
|
+- 构建时间: ~30-60秒 ⚡
|
|
|
|
|
+
|
|
|
|
|
+## 注意事项
|
|
|
|
|
+
|
|
|
|
|
+1. **版本兼容性**: 建议使用Vite 4.x版本,避免Vite 7.x的兼容性问题
|
|
|
|
|
+2. **依赖管理**: 推荐使用yarn而不是npm,避免依赖冲突
|
|
|
|
|
+3. **路径解析**: 确保所有别名路径(@/)正确配置
|
|
|
|
|
+4. **环境变量**: Vite使用VITE_前缀的环境变量
|
|
|
|
|
+5. **插件兼容性**: 某些Vue CLI插件可能需要Vite替代方案
|
|
|
|
|
+6. **模块语法**: 确保所有文件使用ES6模块语法,避免CommonJS与ES6混用
|
|
|
|
|
+7. **导入导出**: 检查所有导入导出语句的兼容性
|
|
|
|
|
+
|
|
|
|
|
+### 16. SCSS 导入和 v-bind() 使用问题
|
|
|
|
|
+
|
|
|
|
|
+**问题**:
|
|
|
|
|
+1. Sass 弃用警告:`Deprecation Warning [legacy-js-api]: The legacy JS API is deprecated`
|
|
|
|
|
+2. SCSS 导入错误:`Can't find stylesheet to import`
|
|
|
|
|
+3. v-bind() 函数未定义错误
|
|
|
|
|
+
|
|
|
|
|
+**解决方案**:
|
|
|
|
|
+
|
|
|
|
|
+#### 16.1 修复 SCSS 变量导入
|
|
|
|
|
+
|
|
|
|
|
+1. 将 SCSS 变量转换为 CSS 自定义属性:
|
|
|
|
|
+
|
|
|
|
|
+```scss
|
|
|
|
|
+// src/styles/variables.scss
|
|
|
|
|
+:root {
|
|
|
|
|
+ --main-bg-color: #f5f5f5;
|
|
|
|
|
+ --base-color: #409EFF;
|
|
|
|
|
+ --nav-height: 76px;
|
|
|
|
|
+ --side-close-width: 65px;
|
|
|
|
|
+ --side-open-width: 160px;
|
|
|
|
|
+ --side-bg-color: #161926;
|
|
|
|
|
+ --side-text-color: #B0B0B0;
|
|
|
|
|
+ --side-active-text-color: #ffd04b;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// 保持 SCSS 变量兼容性
|
|
|
|
|
+$main-bg-color: var(--main-bg-color);
|
|
|
|
|
+$base-color: var(--base-color);
|
|
|
|
|
+$nav-height: var(--nav-height);
|
|
|
|
|
+$side-close-width: var(--side-close-width);
|
|
|
|
|
+$side-open-width: var(--side-open-width);
|
|
|
|
|
+$sideBgColor: var(--side-bg-color);
|
|
|
|
|
+$sideTextColor: var(--side-text-color);
|
|
|
|
|
+$sideActiveTextColor: var(--side-active-text-color);
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+2. 删除旧的 `src/styles/variables.scss.js` 文件
|
|
|
|
|
+
|
|
|
|
|
+3. 更新所有导入旧 `.js` 版本的文件:
|
|
|
|
|
+ - `src/views/IFrame.vue`
|
|
|
|
|
+ - `src/views/AppMain.vue`
|
|
|
|
|
+ - `src/components/layout/components/Logo.vue`
|
|
|
|
|
+ - `src/components/layout/SideBar.vue`
|
|
|
|
|
+
|
|
|
|
|
+4. 在 `src/styles/common.scss` 中直接导入变量文件:
|
|
|
|
|
+
|
|
|
|
|
+```scss
|
|
|
|
|
+@import "./variables.scss";
|
|
|
|
|
+
|
|
|
|
|
+html {
|
|
|
|
|
+ // ... 其他样式
|
|
|
|
|
+}
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+5. 简化 `vite.config.js` 中的 CSS 配置:
|
|
|
|
|
+
|
|
|
|
|
+```javascript
|
|
|
|
|
+css: {
|
|
|
|
|
+ devSourcemap: true,
|
|
|
|
|
+},
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+#### 16.2 使用 v-bind() 绑定响应式 CSS 变量
|
|
|
|
|
+
|
|
|
|
|
+现在可以在 Vue 组件中使用 `v-bind()` 来绑定响应式的 CSS 变量:
|
|
|
|
|
+
|
|
|
|
|
+```vue
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="example-component">
|
|
|
|
|
+ <div class="navbar">
|
|
|
|
|
+ <h3>导航栏高度: {{ nav_height }}</h3>
|
|
|
|
|
+ <button @click="toggleNavHeight">切换高度</button>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref } from 'vue'
|
|
|
|
|
+
|
|
|
|
|
+const nav_height = ref('76px')
|
|
|
|
|
+
|
|
|
|
|
+const toggleNavHeight = () => {
|
|
|
|
|
+ nav_height.value = nav_height.value === '76px' ? '100px' : '76px'
|
|
|
|
|
+}
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.navbar {
|
|
|
|
|
+ height: v-bind(nav_height);
|
|
|
|
|
+ background-color: var(--base-color);
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ padding: 10px;
|
|
|
|
|
+ transition: height 0.3s ease;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|
|
|
|
|
+```
|
|
|
|
|
+
|
|
|
|
|
+**优势**:
|
|
|
|
|
+- 解决了 Sass 弃用警告
|
|
|
|
|
+- 支持 CSS 自定义属性
|
|
|
|
|
+- 可以使用 Vue 3 的 `v-bind()` 功能
|
|
|
|
|
+- 更好的性能和兼容性
|
|
|
|
|
+
|
|
|
|
|
+## 总结
|
|
|
|
|
+
|
|
|
|
|
+通过以上步骤,成功将Vue CLI项目迁移到Vite,获得了显著的性能提升和更好的开发体验。迁移过程主要涉及配置文件的更新和动态导入方式的调整,整体迁移难度适中,值得进行。
|
|
|
|
|
+
|
|
|
|
|
+---
|
|
|
|
|
+
|
|
|
|
|
+**迁移完成时间**: 约2-3小时
|
|
|
|
|
+**主要收益**: 启动速度提升80%,热更新速度提升90%,构建速度提升70%
|