从 Vue2 过渡到 Vue3:JeecgBoot 前端技术栈变了什么
如果你之前用 Vue2 写过项目,第一次打开jeecgboot-vue3的代码目录,可能会觉得既熟悉又陌生。 familiar 的是.vue单文件组件还在,陌生的则是整个工程化链路已经焕然一新。
JeecgBoot 的前端部分基于Vue3 + TypeScript + Vite + Ant Design Vue构建。和 Vue2 时代常用的 Webpack 相比,Vite 的启动速度是肉眼可见的快——这得益于它的预构建机制,本地开发时几乎秒开。TypeScript 的引入则让代码在编写阶段就能捕获类型错误,对从后端转前端的开发者尤其友好。Ant Design Vue 替代了 Vue2 项目中常见的 Element UI,组件 API 风格有所变化,但文档足够详尽,迁移成本可控。
最核心的心态转变是:Vue3 的组合式 API成为默认写法。你不再需要在data、methods、computed之间跳来跳去,而是围绕逻辑功能组织代码。这一点在后面的代码拆解中会看得更清楚。
修改后端接口前缀:从配置到请求拦截
刚拉下来的项目,第一步通常不是写页面,而是把接口调通。JeecgBoot 默认的后端前缀是/jeecg-boot,但生产环境或内网部署时经常需要调整。这里以修改接口前缀为例,走一遍完整的定位流程。
定位环境配置与 API 封装
在项目根目录找到.env文件(或.env.development),里面有一行类似这样的配置:
VITE_GLOB_API_URL=/jeecg-boot这是前端构建时注入的环境变量,决定了所有 API 请求的基础路径。修改它之后,还需要关注src/api目录下的封装逻辑。JeecgBoot 把请求统一封装在axios实例中,通常位于src/utils/http/index.ts或类似路径。
关键看请求拦截器的处理:
// 简化示意,实际路径以项目为准 request.interceptors.request.use((config) => { const token = getToken(); if (token) { config.headers['X-Access-Token'] = token; } // 拼接基础 URL config.url = `${import.meta.env.VITE_GLOB_API_URL}${config.url}`; return config; });这里做了两件事:注入认证令牌和拼接完整请求地址。import.meta.env是 Vite 提供的读取环境变量的方式,和 Vue2 项目里的process.env说再见吧。理解这个拦截流程后,遇到 404 或跨域问题时,你就能快速判断是配置层还是代理层的问题。
拆解一个内置页面:script setup 与响应式实战
光改配置不够过瘾,我们打开一个系统内置页面,看看 Vue3 的写法究竟怎么落地。
script setup:更清爽的组件定义
JeecgBoot 的页面组件普遍采用script setup语法。和传统写法相比,它省去了setup()函数的包裹,顶层变量和函数直接暴露给模板使用:
<script setup lang="ts"> import { ref, reactive } from 'vue' // 定义响应式数据 const count = ref(0) const userInfo = reactive({ name: '张三', role: 'admin' }) // 直接定义方法 function increment() { count.value++ } </script>注意ref和reactive的区别:ref适合基础类型和需要整体替换的场景,访问时要加.value;reactive适合对象类型的深层响应,但不能直接替换整个对象。JeecgBoot 的列表页表单数据常用reactive封装,而弹窗显隐状态这类简单值则用ref。
v-model 的新写法
Vue3 中v-model在自定义组件上的用法也有调整。假设你封装了一个搜索组件:
<!-- 父组件 --> <SearchInput v-model:keyword="searchParams.keyword" /> <!-- SearchInput.vue 内部 --> <input :value="keyword" @input="$emit('update:keyword', $event.target.value)" />:keyword这种带参数的形式替代了 Vue2 里的.sync修饰符,语义更清晰。JeecgBoot 的查询过滤器组件大量使用了这种模式,看懂了这一层,二次封装组件时会顺手很多。
新增菜单与路由:两处配置缺一不可
最后来实操一个高频需求:给系统新增一个功能菜单。JeecgBoot 的菜单体系需要前端路由文件和平台菜单管理两处配合,只改一处是看不到效果的。
前端路由配置
在src/router/routes或类似目录下新增路由定义:
{ path: '/demo/custom-page', name: 'CustomPage', component: () => import('@/views/demo/CustomPage.vue'), meta: { title: '自定义页面', icon: 'icon-dashboard' } }这里component使用动态导入,配合 Vite 实现按需加载。meta里的信息会渲染在侧边栏菜单上。
平台菜单管理
登录系统后,进入系统管理 > 菜单管理,新增一条菜单记录:
| 字段 | 填写说明 |
|---|---|
| 菜单名称 | 显示在导航栏上的名称,如"客户管理" |
| 路由地址 | 对应前端path,注意去掉域名部分,填/demo/custom-page |
| 组件路径 | 对应前端组件的相对路径,如demo/CustomPage |
| 菜单类型 | 选择"菜单"或"目录" |
关键注意点:前端路由的path和平台菜单里填的路由地址必须一致,否则会出现菜单能点、页面空白的情况。另外,如果配置了权限控制,还需要在角色管理里给对应角色分配该菜单的访问权限,否则菜单不会显示。
TypeScript 类型定义:减少编译报错的小技巧
从后端转前端的开发者,最头疼的往往是 TypeScript 的类型报错。这里分享两个 JeecgBoot 项目中常见的写法。
接口响应的通用结构可以定义一个类型:
interface ApiResponse<T = unknown> { code: number message: string result: T } // 使用时指定具体类型 function fetchUserList(): Promise<ApiResponse<User[]>> { return http.get('/sys/user/list') }表单数据推荐用接口约束字段,避免拼写错误:
interface LoginForm { username: string password: string rememberMe?: boolean } const form = reactive<LoginForm>({ username: '', password: '' })养成给reactive和ref标注泛型的习惯,IDE 的提示会更精准,也能在编译阶段拦住不少低级错误。
走完接口配置、页面语法、菜单路由这几个环节,JeecgBoot 的 Vue3 前端开发基本就能上手了。和 Vue2 相比,组合式 API 让代码组织更自由,TypeScript 则在前端工程化层面补上了类型安全的一环。遇到卡壳的地方,优先看项目里已有的页面怎么写,比翻文档来得更直接。