ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Vue 3 项目实战全攻略:从初始化到部署的工程化指南

Vue 3 项目实战全攻略:从初始化到部署的工程化指南 1. 从 0 到 1Vue 项目的初始化和环境搭建1.1 环境准备Node.js 和脚手架选择Vue 项目落地第一步永远是环境。很多新手上来就npm create vuelatest一把梭然后卡在各种依赖安装报错上其实多数问题都出在 Node 版本太老或者 npm 源不稳定上。我在多个环境里验证过Vue 3 项目建议 Node.js 版本不低于 16.14Vite 5 以上则建议 Node 18。要是你本机还停留在 Node 14别纠结直接去官网装 LTS 版本一劳永逸。装完后用node -v和npm -v确认版本这两个命令能输出版本号环境就算通了。脚手架方面官方推荐create-vue它基于 Vite启动速度快、构建效率高打包产物也比 webpack 时代小不少。执行下面这条命令npm create vuelatest它会交互式地问你要不要装 TypeScript、Vue Router、Pinia、ESLint、Prettier 等按需勾选即可。个人建议新手全选 No 先把项目跑起来后面需要再加否则配完反而看不懂。注意如果你的网络环境导致 npm 安装慢或频繁超时可以先把 npm 源切到国内镜像执行npm config set registry https://registry.npmmirror.com实测下载依赖速度和稳定性提升非常明显。1.2 VSCode 里创建和运行 Vue 项目的两种方式VSCode 是当前 Vue 开发的绝对主力编辑器很多热词里都在问vscode怎么创建vue项目通常有两种方式。第一种直接用命令行打开 VSCode 的终端Ctrl输入上面的npm create vuelatest命令按提示填写项目名和选项然后cd 进项目目录安装依赖npm install npm run dev第二种是用 VSCode 的 GUI 集成如果你装了 Volar 扩展在 VSCode 左侧的源代码管理面板里也可以看到项目状态但创建项目本身还是离不开命令行的。依赖安装完成后npm run dev启动开发服务器终端会输出本地访问地址例如http://localhost:5173浏览器打开即可看到 Vue 的欢迎页面。整个流程走通你的 Vue 开发环境就算齐活了。1.3 Vue Devtools 插件的安装和验收热词里很多人问 vue devtools 插件下载这里多说一句Vue Devtools 是 Vue 项目调试的核心工具没有它你排查组件状态、路由跳转、Store 数据流都像蒙着眼睛走路。新版本 Devtools 推荐安装方式有两种Chrome 应用商店直接搜索 Vue.js devtools 安装安装完会在浏览器工具栏出现 Vue 图标。如果你用 Firefox 或 Edge同样有对应插件版本直接在各自商店搜索安装即可。装完验证是否生效的方法很简单切到 Vue 项目页面打开 F12 开发者工具如果多了一个 Vue 面板说明插件生效了。如果没出现通常是生产环境页面检测不到框架只有在开发环境即npm run dev启动的本地页面下 Devtools 才会激活。这里有个易踩的点Vue 3 项目需要安装新版 Devtoolsv6老版本插件只认 Vue 2装上后 Vue 面板死活不出来很多人卡在这一步。装完插件再去组件选项卡里看 props、data、computed 和路由信息调试效率提升不是一点半点。2. 核心开发路由、状态管理和组件通信2.1 Vue Router 路由参数传递与路由拦截器Vue 项目几乎绕不开路由尤其是单页面应用。热词里大量出现vue路由vue路由参数vue路由拦截器说明这几个点是新手最容易迷糊的。路由参数传递有两条路线第一条是路径参数// 定义路由时声明参数 const routes [ { path: /user/:id, component: UserDetail } ] // 跳转时传参 // 方式一路径字符串拼接 router.push(/user/${userId}) // 方式二命名路由 参数对象 router.push({ name: user-detail, params: { id: userId } }) // 页面里接收参数 const route useRoute() const id route.params.id第二条是 query 参数适合传递非必须的筛选条件或页面标识router.push({ path: /list, query: { keyword: vue, page: 1 } }) // 接收 const keyword route.query.keyword这两者的区别记住一句话params 参数会改变路径结构刷新后参数仍在query 参数拼接在 URL 后面类似?keywordvue。选哪种取决于你的业务语义标识资源用 params描述筛选条件用 query。路由拦截器导航守卫解决的是进入页面前先做鉴权或校验的问题。最常见的使用场景是登录校验未登录用户跳到登录页router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.meta.requiresAuth !token) { next({ name: login }) return } next() })配合路由 meta 字段可以给不同页面设定不同的访问权限。还有一点容易忽略路由守卫里做异步校验比如调接口确认用户权限时记得加 loading 状态否则页面跳转会有长长的白屏用户体验很差。2.2 Pinia vs Vuex状态管理选型与实战热词里专门有一个 vue pinia vs vuex这个问题我在社区里回答过无数次现在方向已经非常明确了Vue 3 新项目无脑选 PiniaVue 2 老项目才继续用 Vuex。Pinia 相比 Vuex 的核心优势用大白话说就是少写很多模板代码。Vuex 的写法是固定的四件套state、mutations、actions、getters改一个数据要先 dispatch 一个 action再 commit 一个 mutation链路很长。而 Pinia 直接干掉了 mutations同步修改就是 state 直接赋值异步操作在 actions 里写完直接用还天然支持 setup 风格import { defineStore } from pinia export const useUserStore defineStore(user, { state: () ({ name: , age: 0 }), getters: { // 自动推断类型无需额外声明 doubleAge: (state) state.age * 2 }, actions: { // 异步更新数据无需 commit async fetchUser() { const res await api.getUser() this.name res.data.name this.age res.data.age } } })Pinia 还天然支持模块化——定义多个 store 文件组件里分别引入即可不需要像 Vuex 那样手动注册 modules心智负担小很多。说个实操中的体会用 Pinia 时不要在组件里到处解构 store 的 state一旦结构化了响应式就断了。正确做法是要么用storeToRefs()要么直接拿整个 store 对象用例如import { storeToRefs } from pinia import { useUserStore } from /stores/user const store useUserStore() const { name, age } storeToRefs(store) // 保持响应式2.3 组件通信与 Composable 设计思路composable vue 这个热词说明大家开始关注逻辑复用了。Vue 3 组合式 API 的核心思想就是把一块业务逻辑包含响应式数据和方法封装成一个函数谁要用谁引入类似 React 的 Custom Hook。举个例子常见的列表加载更多逻辑可以封装成 composable// usePagination.js import { ref, computed } from vue export function usePagination(fetcher, initialPage 1) { const list ref([]) const page ref(initialPage) const loading ref(false) const hasMore ref(true) async function loadMore() { if (loading.value || !hasMore.value) return loading.value true try { const data await fetcher(page.value) list.value.push(...data.items) hasMore.value data.hasMore page.value 1 } finally { loading.value false } } return { list, page, loading, hasMore, loadMore } }注意这里用ref包裹的变量在返回后依然保持响应式组件里直接loadMore()就能触发加载。这种设计让一个几十行的列表逻辑变成一个函数的调用多个页面能直接复用后续维护只改一处爽得不行。封装 composable 有个原则我建议遵守单一职责。一个 composable 只做一件事比如useUserInfo、useTableData、usePermission各自独立互相通过参数传递数据。千万别写一个万能 composable把什么都塞进去那还不如不封装。3. 工程化实战前后端联调、Token 处理和构建打包3.1 Spring Boot Vue 前后端分离联调中的跨域问题热词里 springboot vue前后端分离 fastapi vue前后端分离 都很常见基本所有企业级项目都是这个架构。前后端分离带来的第一个问题就是跨域。开发环境下前端跑在localhost:5173后端跑在localhost:8080端口不同浏览器默认会拦截跨域请求。最常用的解决方案是 Vite 代理在vite.config.js里配置export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true } } } })这样前端请求/api/user/list时Vite 开发服务器会把它转发到http://localhost:8080/api/user/list跨域问题就绕开了。注意配置完要重启npm run dev才能生效这个坑我踩过很多次。生产环境下通常由 Nginx 做反代location /api/ { proxy_pass http://127.0.0.1:8080/api/; }前端代码里请求路径统一写/api/xxx开头无论在开发环境还是生产环境都能正确转发这是前后端分离联调的最佳实践之一。3.2 请求 Token 的携带与刷新处理vue前后端分离请求token处理 是另一个高频话题。主流的方案是 JWT Token 鉴权用户登录后后端返回一个 token前端存到 localStorage 或 cookie 里后续每个请求都在请求头带上// axios 请求拦截器 import axios from axios const service axios.create({ baseURL: /api, timeout: 10000 }) service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config })响应拦截器里集中处理 401 未授权的情况比如 token 过期就跳登录页service.interceptors.response.use( response response.data, error { if (error.response?.status 401) { localStorage.removeItem(token) router.push({ name: login }) } return Promise.reject(error) } )有个容易被忽视的细节多个请求并发时如果同时返回 401会触发多次跳转登录页的尴尬情况。建议加一个标志位控制只让第一个 401 触发跳转后面的直接放行。还有一个进阶玩法是 token 刷新机制access token 过期后用 refresh token 换取新的 access token然后重放之前被拦截的请求。这个方案能显著提升用户体验但实现复杂度也会上一个台阶。如果你做的是 C 端产品这一步值得投入内部管理系统的话401 跳登录就够用了。3.3 Vue 打包后布局异常的常见原因和排查“vue 打包后布局异常”这个问题出现频率极高开发环境一切正常npm run build部署到服务器后页面乱了样式丢了资源 404。先说资源路径问题。默认情况下 Vite 打包出来的静态资源路径是绝对路径/assets/xxx.js如果你的项目部署在服务器子目录下比如http://example.com/myapp/那么这些绝对路径就全部 404 了。解决办法是在vite.config.js里设置 baseexport default defineConfig({ base: ./, // 改用相对路径 // 或者写成 /myapp/ })再说 CSS 布局错乱。很多情况下是构建时样式顺序被压缩或合并导致选择器优先级变化尤其是用了大量深选择器:deep()覆盖第三方组件样式的时候。解决办法是尽量避免全局覆盖组件内部样式改用组件 scoped 内的:deep()或者用 CSS 变量进行主题定制。还有一个隐蔽的问题打包后使用了某些浏览器新特性如backdrop-filter在低版本浏览器上不生效导致布局错乱。排查顺序建议是先看浏览器控制台报错 → 再检查资源路径 → 最后看样式覆盖情况。多数布局异常都是这三步里能定位到的。3.4 多个表格导出一个 Excel 的实现思路vue多个表格导出一个excel 这个需求在实际后台管理系统中非常常见比如批量导出多个业务表到一个工作簿。社区里最成熟的方案是xlsx库配合file-savernpm install xlsx file-saver核心代码并不复杂import * as XLSX from xlsx import { saveAs } from file-saver function exportMultipleSheets(sheets) { const workbook XLSX.utils.book_new() sheets.forEach(({ name, headers, data }) { const worksheet XLSX.utils.json_to_sheet(data, { header: headers }) XLSX.utils.book_append_sheet(workbook, worksheet, name) }) const buf XLSX.write(workbook, { type: array, bookType: xlsx }) saveAs(new Blob([buf], { type: application/octet-stream }), export.xlsx) }实际项目里表格的数据往往分布在不同的接口里导出时需要注意接口并发顺序。建议用Promise.all同时拉取所有表格数据等全部返回后再组装 workbook减少用户等待时间。另一个常见的坑中文列名的表头如果直接用json_to_sheet生成默认列头是key的英文名。解决方法是传header选项指定表头或者在json_to_sheet前手动给数据对象加中文字段映射。我一般推荐后者因为更直观const exportData rawData.map(item ({ 姓名: item.name, 订单号: item.orderNo, 金额: item.amount }))4. 场景化集成M3U8 视频播放、地图组件、WebSocket 与多周选择4.1 Vue 项目中播放 M3U8 视频流热词里 vue播放m3u8 vue视频m3u8 出现多次。M3U8 是 HLSHTTP Live Streaming协议的索引文件常用于直播和点播场景浏览器原生不支持直接播放需要借助hls.js这个库。安装并封装一个可复用的播放组件npm install hls.jstemplate video refvideoRef controls playsinline stylewidth: 100%/video /template script setup import { ref, onMounted, onBeforeUnmount } from vue import Hls from hls.js const props defineProps({ src: { type: String, required: true } }) const videoRef ref(null) let hls null onMounted(() { const video videoRef.value if (Hls.isSupported()) { hls new Hls({ maxBufferLength: 30 }) hls.loadSource(props.src) hls.attachMedia(video) } else if (video.canPlayType(application/vnd.apple.mpegurl)) { // Safari 原生支持 HLS video.src props.src } }) onBeforeUnmount(() { if (hls) hls.destroy() }) /script这里有个经验要提一下hls.js实例用完后一定要调用destroy()否则多页面切换时会产生内存泄漏和播放卡顿。我踩过一次坑切到别的路由再切回来视频就一直黑屏查了半天发现是上一个页面的 Hls 实例没有销毁。另外M3U8 播放地址如果涉及跨域需要在服务端配置 CORS 头否则会出现媒体加载失败的错误。这个属于后端配置但前端排查时也要有这个意识不要把锅全甩给播放器。4.2 Vue 里集成腾讯地图组件的方案热词里有用在vue里的腾讯地图这也是一个高频需求。无论是配送类系统、门店系统还是物业项目地图都是常见的组件。使用腾讯地图 Vue 版的方式并不复杂官方提供了qqmap-wx-jssdk和普通 JavaScript API。在 Vue 3 项目里我推荐按需要动态加载脚本而不是在index.html里全局引这样可以减少首屏加载压力// utils/loadMap.js let cachePromise null export function loadTencentMap() { if (cachePromise) return cachePromise cachePromise new Promise((resolve, reject) { const script document.createElement(script) script.src https://map.qq.com/api/gljs?v1.expkeyYOUR_KEY script.onload () resolve(window.TMap) script.onerror reject document.head.appendChild(script) }) return cachePromise }组件里使用script setup import { onMounted, ref } from vue import { loadTencentMap } from /utils/loadMap const mapRef ref(null) onMounted(async () { const TMap await loadTencentMap() const map new TMap.Map(mapRef.value, { center: new TMap.LatLng(39.908860, 116.397390), zoom: 15 }) // 添加标记点 const marker new TMap.Marker({ position: new TMap.LatLng(39.908860, 116.397390), map: map }) }) /script这里要特别提醒腾讯地图 API 的 Key 需要先在腾讯位置服务官网申请并把你的域名地址加入白名单。开发调试时用localhost访问必须在白名单里加http://localhost:5173否则地图不渲染控制台会给出 INVALID_KEY 之类的报错信息。4.3 Vue 中接入 WebSocket 与多周选择组件热词里 vue 增加 websocket 和 vue选择多周组件 两个需求看起来不相关但都属于前端集成里的典型场景。WebSocket 在 Vue 里的标准接入方式是封装一个 composable管理链接状态、自动重连和消息分发// useWebSocket.js import { ref, onUnmounted } from vue export function useWebSocket(url) { const socket ref(null) const connected ref(false) const messages ref([]) function connect() { socket.value new WebSocket(url) socket.value.onopen () { connected.value true } socket.value.onmessage (event) { messages.value.push(JSON.parse(event.data)) } socket.value.onclose () { connected.value false // 自动重连5 秒后重新连接 setTimeout(connect, 5000) } } function send(data) { if (connected.value) { socket.value.send(JSON.stringify(data)) } } onUnmounted(() { socket.value?.close() }) connect() return { connected, messages, send } }注意 WebSocket 在组件卸载时必须手动关闭否则连接会一直存在不仅造成资源浪费还可能因为后端主动断开导致控制台报错刷屏。多周选择组件指的是能同时选择多个连续自然周的日期选择器比如排班系统里选择第 3 周到第 8 周。如果找不到现成的组件可以基于v-calendar或element-plus的日期面板自行封装。核心思路是把周作为最小单位点击一个周单元格选中该周点击另一个周单元格则选中两仓之间的所有周。实现时用一个range数组记录起止周即可const selectedWeeks ref([]) function handleWeekClick(weekIndex) { if (selectedWeeks.value.length 0) { selectedWeeks.value [weekIndex] } else if (selectedWeeks.value.length 1) { const [start] selectedWeeks.value selectedWeeks.value [Math.min(start, weekIndex), Math.max(start, weekIndex)] } else { selectedWeeks.value [weekIndex] } }4.4 Vue 中使用 html5-qrcode 实现扫码登录vue html5-qrcode 这个热词背后是扫码登录或扫码开票的常见需求。html5-qrcode是一个能在浏览器端调用摄像头解码二维码的库兼容性不错。npm install html5-qrcode核心用法script setup import { onMounted, ref } from vue import { Html5Qrcode } from html5-qrcode const scannerRef ref(null) let scanner null onMounted(async () { scanner new Html5Qrcode(qr-reader) try { await scanner.start( { facingMode: environment }, { fps: 10, qrbox: { width: 250, height: 250 } }, (decodedText) { console.log(扫码结果:, decodedText) scanner.stop() } ) } catch (err) { console.error(摄像头开启失败, err) } }) onBeforeUnmount(() { scanner?.stop() }) /script template div idqr-reader refscannerRef/div /template实际项目里扫码后通常要立刻轮询后端接口确认扫码状态已扫码、已确认、已过期所以需要配合一个定时器比如每 2 秒查一次来判断扫码状态流转。另外真机测试时摄像头权限需要在 HTTPS 或 localhost 环境下才能请求正常这点要提前知道否则部署到非 HTTPS 的内网服务器上才发现摄像头打不开会非常被动。5. 项目实战从 Spring Boot Vue 到若依框架部署5.1 基于 Spring Boot Vue 的完整项目结构设计热词里多次出现的 基于springboot vue的在线点餐系统基于 django vue 的流浪动物领养管理系统web vue 开发 配电工艺图 都属于前后端分离的业务系统开发。这类项目的核心难点不在技术而在结构。标准的前后端分离项目前端通常是frontend/ ├── src/ │ ├── api/ # 接口请求统一封装 │ ├── assets/ # 静态资源 │ ├── components/ # 通用组件 │ ├── composables/ # 组合式函数 │ ├── directives/ # 自定义指令 │ ├── layouts/ # 布局组件 │ ├── router/ # 路由配置 │ ├── stores/ # Pinia 状态管理 │ ├── utils/ # 工具函数 │ ├── views/ # 页面组件 │ ├── App.vue │ └── main.js ├── index.html ├── package.json └── vite.config.js后端以 Spring Boot 为例则是标准的 controller / service / mapper 分层。联调时的关键是在api目录里按业务模块拆分接口文件例如api/user.js、api/order.js一个文件只管一个模块的请求前后端人员对着文档就能快速定位问题。5.2 若依RuoYiVue 开源项目在 IDEA 中的部署这个热词非常典型若依 vue 开源项目在idea 中部署。若依是目前国内使用率极高的后台管理脚手架基于 Spring Boot Vue 前后端分离代码规范、权限模型完整非常适合做企业内部系统的起点。在 IDEA 里部署若依 Vue 3 版本流程大致是后端部分用 IDEA 打开ruoyi-vue后端代码等待 Maven 下载依赖。在application-druid.yml里配置你的 MySQL 数据库连接若依默认数据库是ry-vue需要先导入源码里提供的sql目录下的建库脚本。配置 Redis 连接信息若依的验证码和登录状态依赖 Redis。启动RuoYiApplication.java主类看到 若依启动成功 的日志就是起来了。前端部分用 VSCode 打开ruoyi-ui目录。执行npm install安装依赖若依的依赖较多耐心等待。执行npm run dev默认端口 80在vue.config.js里配置浏览器访问http://localhost:80。若依部署常见的坑有两个一是数据库字符集没设置成utf8mb4导入 SQL 时报错二是 Redis 没启动验证码图片不显示。按顺序检查这两项能解决大部分新手的问题。5.3 Vite 构建优化与常见警告处理热词里有一条英文报错信息值得单独拿出来讲ignored build scripts: cpu-features0.0.10, esbuild0.21.5, ssh21.17.0这通常出现在npm install时npm 为了安全默认忽略了这些依赖包中的 postinstall 脚本。esbuild被忽略构建脚本会导致一个明显的后果Vite 启动时提示esbuild二进制文件缺失或不匹配虽然多数情况下 npm 会通过平台包esbuild/win32-x64等正常安装二进制文件但某些环境确实会出问题。一个有效的解决办法是执行npm rebuild esbuild让 esbuild 的安装脚本重新执行生成对应的二进制文件。如果还不行删除node_modules和package-lock.json重新安装或者升级 npm 到最新版本实测大多数场景都能恢复。另一个高频警告是 Volar 相关的提示。热词里出现了 in the vue 3 project, the vue language features (volar) is new recommended这是 VSCode 在 Vue 3 项目里提示你禁用老旧的 Vetur 插件并启用 Volar。如果你同时开着 Vetur 和 Volar模板语法提示会互相干扰。我的做法是直接禁用 Vetur只保留 Vue Language Features (Volar)并把 Volar 的 Takeover Mode 打开VSCode 右下角点 Volar 图标切换配合 TypeScript Vue Plugin 使用类型提示和自动补全都非常流畅。5.4 Vue UI 自动断开和运行异常排查vue ui 自动断开 是 Vue CLI 时代遗留的高频问题现在用 Vite 的团队变少了但老项目里仍然存在。Vue UI 是 Vue CLI 自带的图形化项目管理界面自动断开常见原因有Node 版本过高或过低导致vue/cli内部依赖冲突。端口被占用Vue UI 默认监听8000如果你本地有其他服务占了端口界面就会反复断开重连。系统休眠或网络切换后 websocket 连接失效Vue UI 无法自动恢复。解决思路是优先升级vue/cli到最新版本在 Node 16 和 Node 18 之间切换以排除兼容问题如果只是项目管理直接命令行操作不必依赖 GUI。另外开发环境下 Vite 的 WebSocket 连接也会偶发断开表现为页面热更新失效、控制台报 WebSocket connection to ws://localhost:5173 failed。这种情况先把 Vite 服务停掉重新启动排查一下是否有代理服务占用了同一端口或者检查防火墙和代理配置。极少数情况下公司网络的代理设置会影响本地 WebSocket需要在 Vite 配置里把server.host设置为127.0.0.1或0.0.0.0显式绑定。6. 前端进阶国际化、TypeScript、PWA 与安全加固6.1 Vue I18n 国际化与 HTML 标签插入热词里有一个很具体的问题vue i18n 怎么在{0}里插入 html标签。这是 Vue I18n 使用中的经典需求比如你要显示一句话请阅读用户协议但用户协议需要是一个可点击的链接。Vue I18n 有一套专门处理这种场景的语法叫做命名插值 子组件渲染方式。如果你的消息文本是纯文本正常写法是const messages { zh: { welcome: 欢迎回来{name} } }在模板里用template p{{ t(welcome, { name: 张三 }) }}/p /template但如果要在{0}或{name}的位置插入 HTML 标签比如给用户协议加个链接纯插值解决不了。官方推荐用--结尾的插值语法配合i18n-t组件实现// 语言文件 const messages { zh: { agreement: 请阅读我们的 {agreement} 以继续使用, agreementLink: 用户协议 } }template i18n-t keypathagreement tagp template #agreement a href/terms target_blank{{ t(agreementLink) }}/a /template /i18n-t /template这样就能在翻译文本的{agreement}位置注入 HTML 内容而不是把整段文字用v-html粗暴拼接既安全又灵活。这里要提一句尽量避免在生产翻译文本中使用v-html渲染整段 HTML因为你无法保证翻译内容里没有恶意脚本XSS 风险会被无限放大。用i18n-t组件把动态部分隔离出来是推荐的安全做法。6.2 TypeScript 在 Vue 3 项目中的接入typescript vue springboot 这个热词组合说明很多人开始用 TS 重写 Vue 前端了。Vue 3 原生支持 TypeScriptVite 脚手架在创建项目时也可以直接勾选 TS 选项。TS 在 Vue 里的核心价值是类型安全props 类型错误会在编译期暴露接口返回的数据结构一目了然。一个典型的带类型约束的组件写法script setup langts interface UserInfo { id: number name: string email: string role: admin | user } const props defineProps{ user: UserInfo showEmail?: boolean }() const emit defineEmits{ (e: update, user: UserInfo): void }() /script这样写的好处是调用方传入不符合UserInfo结构的对象时VSCode 里会直接标红根本不需要等到运行时才发现数据读不到undefined。特别是后端接口返回的字段一旦改动前端类型定义同步更新所有引用处都会第一时间暴露问题。如果你是从纯 JS 项目迁移到 TS不用急着一步到位。建议先把vite.config.ts和router目录迁移成 TS然后把组件内defineProps和defineEmits加上类型最后再补接口层的类型定义。这样渐进式迁移每步改动量可控回归风险低。6.3 Angular 与 Vue 的核心差异热词里 angular和vue区别 angular和vue有什么不同 被问了这么久这里用最直白的话总结。Angular 是完整的框架自带路由、HTTP 客户端、表单处理、依赖注入、测试工具全部给你配齐使用方式也是固定的模块 依赖注入 装饰器模式。Vue 更像是渐进式库核心是响应式数据绑定和组件系统路由、状态管理、构建工具全都需要你按需选择。从选型角度讲Angular 适合大型企业级应用团队需要统一的规范和完整的约束Vue 更适合快速开发和中小型项目上手门槛低生态灵活。如果你的团队里有 Java 背景的同学可能会更适应 Angular 的依赖注入风格如果你的团队以 UI 为主Vue 更好上手。Angular 的变更检测机制也比 Vue 复杂性能优化方面 Vue 有更清晰的边界。面试题里常问的Vue 双向绑定原理虚拟 DOM 和真实 DOM 对比在 Angular 里对应的则是脏检查与 Zone.js这俩机制的底子决定了框架的处理模型完全不同。6.4 Vue 3 项目中的 SQL Viewer 与低代码思路vue sql-viewer 这个热词指的需求是在浏览器里展示和编辑 SQL 语句。常见于后台管理系统的数据报表模块、低代码平台或数据库管理界面。一个成熟的 sql-viewer 组件需要支持语法高亮、格式化、代码折叠、错误提示等功能。实现方案上有两条路第一条是直接引入键路径上现成的库如codemirror的codemirror/lang-sql配合sql-formatter做格式化npm install codemirror/lang-sql sql-formatterimport { basicSetup } from codemirror import { EditorView } from codemirror/view import { sql } from codemirror/lang-sql import { sql as formatSql } from sql-formatter const editor new EditorView({ doc: SELECT * FROM users WHERE id 1, extensions: [basicSetup, sql()], parent: document.getElementById(editor) })格式化时直接formatSql(sqlText, { language: mysql })即可。第二条是使用 monaco-editorVS Code 同款编辑器适合功能更强的 SQL 编辑器。monaco 体积较大需要按需加载但语法高亮、智能提示、对比视图一应俱全适合做复杂的在线 SQL 工具。我个人的建议是简单的只读展示用 CodeMirror 就足够了加载快、定制简单如果需要做复杂的在线编辑器包含多标签页、语法校验、快捷输入就直接上 Monaco体验感拉满。7. 调试与排查Vue 项目踩坑速查表7.1 高频报错与解决方案对照把热词和实际项目中高频出现的问题整理成速查表按出现频率排序。报错/问题常见原因解决思路Failed to resolve import路径写错或模块未安装检查 import 路径安装了依赖后重启 dev serverCannot read properties of undefined (reading xxx)接口数据未返回或结构不对先 console.log 打印数据确认字段存在再加空值判断[Vue warn]: Property xxx was accessed during render but is not defined模板里用了未定义变量检查 data 或 setup 返回值确认变量名拼写TypeError: Cannot read properties of null (reading xxx)DOM 元素未渲染就获取使用nextTick或在onMounted里获取esbuild: Failed to install correctlyesbuild 二进制文件缺失执行npm rebuild esbuild或删除 node_modules 重装404 on assetsbase 路径配置错误vite.config.js 里设置base: ./Loading failed for the script with source静态资源路径不对检查 public 目录引用方式有个现象值得一提项目里遇到报错时我习惯先看浏览器控制台的最新一条 error大多数 Vue 的报错信息其实已经把原因写得很直白了只是很多人被一堆堆栈吓住了。先翻译报错关键字再按图索骥效率远高于盲目改代码。7.2 经典面试题Vue 响应式原理与虚拟 DOM热词里也有 vue面试题。面试题范围很广但最常问、也最能体现水平的还是两个响应式原理和虚拟 DOM。Vue 3 的响应式基于 ES6 的 Proxy核心点可以概括为track收集依赖 trigger触发更新。你在 setup 里声明的ref和reactive底层都会变成 Proxy 对象读取属性时收集该属性的依赖哪些组件在用修改属性时通知这些依赖重新渲染。相比 Vue 2 用Object.defineProperty逐字段劫持Proxy 支持动态新增属性、数组索引变化、删除属性覆盖面完整得多。虚拟 DOM 的核心思路是不要每次数据变化都直接操作真实 DOM而是先在内存里用 JS 对象描述树结构虚拟节点对比新旧虚拟节点diff 算法找出变化的最小范围再一次性更新到真实 DOM。Vue 3 对 diff 算法做了静态树提升、patchFlag 等优化性能在常见场景下比 Vue 2 快不少。面试回答时能结合一个具体例子讲解比如点击按钮修改数组某一项Vue 是怎么重新渲染的会比背概念加分很多。7.3 编码规范与团队协作的心得最后聊点软性的。我在带团队时最强调的一点是Vue 项目的可维护性比 能跑起来 重要得多。一套好的编码规范能减少一半的无意义沟通。几个我在实际项目中坚持的原则组件命名统一用 PascalCase比如UserCard.vue文件名和组件名保持一致。组件文件里 template 结构遵循先标签后逻辑script setup 里先定义 props再定义 emit再定义响应式数据最后定义方法顺序固定对代码 review 友好。不要在一个组件里塞超过两百行的模板拆分子组件是义务而不是可选项。所有接口调用必须走api目录统一封装严禁在组件里直接写axios.get。使用 ESLint Prettier提交代码前跑一遍自动修复格式问题不靠人肉盯。搭项目的初期花半天时间把这些规范定好后面省下的时间绝对远超这半天的投入。特别是当你开始接手别人写的代码或者你的代码要被别人接手时这种体会会非常深。8. 部署与未来从项目上线到持续迭代8.1 Vue 项目的部署流程和 Nginx 配置项目开发完要上线vue 打包 后如何部署也是一个绕不开的话题。以最常见的 Nginx 为例一个典型 Vue 单页应用的配置server { listen 80; server_name your-domain.com; root /var/www/vue-project/dist; index index.html; # 前端路由需要 history 模式支持 location / { try_files $uri $uri/ /index.html; } # 静态资源缓存 location /assets/ { expires 7d; add_header Cache-Control public, max-age604800; } # 后端 API 反向代理 location /api/ { proxy_pass http://127.0.0.1:8080/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }try_files $uri $uri/ /index.html这行是单页应用的核心所有不存在的路径都返回index.html由前端路由接管。没有这行配置直接在浏览器刷新/user/123会 404这是部署中最常见的坑之一。构建机器上执行npm run build后dist目录就是全部静态产物丢到 Nginx 的 root 目录即可。CI 流程成熟的公司会把这一步做成自动化流水线push 到 main 分支后自动构建并发布到服务器但核心配置思路完全一致。8.2 老项目、低代码工具与个人方向思考热词里有几个方向暗示了 Vue 生态的扩散方向包括低代码平台、物联网虚拟大屏配电工艺图以及各类管理系统。这些都是 Vue 的典型应用场景尤其是管理后台领域Vue Element Plus Pinia ECharts 的组合几乎成了事实标准。用 Vue 做配电工艺图这类工艺流程图 数据可视化项目选择一个靠谱的图形库很重要。方案通常是ECharts做统计图表和部分拓扑图AntV X6或LogicFlow做可交互的工艺流程图和拓扑编辑基于 SVG 的svg.js做自定义图形渲染。这类项目的核心难点在数据组织图上每个节点的位置、状态、关联关系都要有结构化的数据支撑前端负责把数据映射成图形和样式。架构上建议把图形的数据模型和视图渲染解耦后续需求变动比如新增节点类型、连线规则时只改配置数据不改渲染逻辑维护成本会低很多。对个人开发者来说Vue 生态的成熟度已经很高无论是找外快做小系统还是自研产品技术栈选 Vue 几乎不会踩大坑。选择一个垂直领域深耕如工业可视化、GIS 可视化、低代码平台比停留在会写页面的层面更有长期价值。我在实际项目里的感受是Vue 看似代码量不多但真正决定项目好坏的是架构设计和工程化规范。环境配好、目录结构清晰、状态管理合理、权限边界明确后面的开发节奏就能很顺。如果你正准备从一个会写 Vue 组件的阶段跨到撑起一个完整项目的阶段可以优先把上面这些工程化、部署、调试和选型经验吃透很多坑就不会再踩了。最后再安利一个开发习惯每次遇到问题解决后随手把报错信息和解决办法记录到项目的docs/troubleshooting.md里哪怕只有一句话。这些记录攒几个月再看会发现自己解决的很多问题在团队里反复发生直接形成一本团队内部排错手册对新人上手帮助特别大。
返回列表