ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Vue 技术栈从入门到实战:环境搭建、路由传参、m3u8 播放与前后端分离 token 处理全指南

Vue 技术栈从入门到实战:环境搭建、路由传参、m3u8 播放与前后端分离 token 处理全指南 刚开始看到“vue.9”这个标题时我第一反应是某个版本号比如 Vue 2.9 或者某本书的第 9 章。但联系到近期大家频繁搜索的 vue 安装、路由传参、m3u8 播放、前后端分离 token 处理这些关键词我明白了——这不是一个具体的插件或者某个单一项目而是一整套围绕 Vue 的技术栈整理。简单说这就是一条从入门到实战的完整路线图环境怎么搭、路由怎么写、状态管理怎么选、视频怎么播、后端怎么连、打包后布局乱了怎么排查。这篇文章面向的是两类人一类是刚接触 Vue 不久被茫茫多的工具链和概念搞得有点晕的初学者另一类是已经能写一些页面但遇到路由守卫、token 过期、跨域、打包部署这类实际问题时需要一份可以直接照着做的排查手册。我会按照项目从创建到上线的实际推进顺序来讲把搜到的热词全部串进去顺便把我实测中踩过的坑也一并写出来。1. 环境准备与项目初始化这一步决定了后面八成的问题1.1 Node.js 安装与版本选择的几个关键细节不管你是要用 Vue CLI 还是最新的 Vite第一步永远是装 Node.js。很多初学者随手装一个最新版然后发现某些老项目跑不起来或者装了半天依赖总是报错八成就是 Node 版本不对。目前实际情况是Vue 2 项目搭配 Node 14 到 16 比较稳妥Vue 3 项目推荐 Node 16 以上如果要用 Vite 5 或更新版本Node 版本需要 18。用node -v和npm -v检查一下自己的版本如果版本不对不用卸载重装直接装一个 nvmNode Version Manager来管理多版本。切换命令很简单nvm install 16.20.2然后nvm use 16.20.2。依赖安装慢是另一个高频问题。国内直接用npm install往往会卡很久建议全局切换到镜像源执行一次npm config set registry https://registry.npmmirror.com后面所有项目的下载速度都会有质的提升。装了 pnpm 的话pnpm 也可以走这个镜像统一在.npmrc里写registryhttps://registry.npmmirror.com即可。注意不要用 cnpm 安装依赖。cnpm 有时候会改变依赖的目录结构导致后续某依赖找不着一路报错排查起来非常费劲。镜像源可以换包管理器建议老老实实用 npm 或 pnpm。1.2 从 Vue CLI 到 Vite项目创建方式的变化以前我们创建一个 Vue 项目默认是vue create my-project用的是 Vue CLI底层基于 Webpack。现在官方推荐的是 Vite创建命令是npm create vuelatest注意这里创建的是 Vue 3 项目过程中会询问你是否需要 TypeScript、Vue Router、Pinia、ESLint 等推荐全部选上后面写代码时这些内置配置能省很多事。如果是公司已有老项目还在用 Vue CLI也不要急着迁移。CLI 的成熟生态和 Webpack 的兼容性在维护老项目时反而是优势。但任何新项目建议直接 Vite开发服务器启动速度快到一个离谱的程度热更新也几乎是秒级响应。创建完项目后进入目录安装依赖cd my-project npm install npm run dev看到Local: http://localhost:5173/这样的输出就说明项目已经跑起来了。1.3 IDE 与 Vue 官方插件的坑写 Vue 3 项目时Volar 已经是事实上的标准插件。如果之前用过 Vetur建议在 Vue 3 项目里把它禁用否则两个插件同时生效会产生一些奇怪的代码提示和类型报错。Volar 安装后第一步把它的 Takeover Mode接管模式打开在 VS Code 里按CtrlShiftP输入Vue: Switch to Takeover Mode。这样 TS 和 Vue 的文件都由 Volar 接管类型提示和 node_modules 里的解析会更快更准。此外Typescript 的 vue 文件诊断有时会误报遇到这种情况在设置里搜索vue.server.hybridMode如果开着就临时关掉试试多数能解决。2. 路由设计从基本传参到完整鉴权链路2.1 动态路由传参的各种姿势Vue Router 4 是 Vue 3 项目的标配路由传递参数的方法大概有三种路径参数、查询参数query、以及通过路由元信息meta附带数据。路径参数的定义方式{ path: /detail/:id, name: Detail, component: () import(../views/Detail.vue) }跳转时有两种写法// 字符串方式 router.push(/detail/1024) // 对象方式更适合传多个参数 router.push({ name: Detail, params: { id: 1024 } })接收参数时在模板里用$route.params.id在组合式 API 里用useRoute()后route.params.id读取。query 参数比较适合传一些可选的筛选条件比如列表页跳转时保留搜索关键词router.push({ path: /list, query: { page: 2, keyword: vue } }) // 读取 route.query.page还有一个容易被忽略的细节params不能和path混用。必须使用name加params的组合方式因为path会被直接作为字符串匹配路径/detail/1024这种场景用路径参数显然更合理而query天然支持任意 URL 拼接。动态路由也需要注意组件复用问题。同一个组件实例在/detail/1和/detail/2之间切换时因为组件被复用onMounted并不会重新触发。正确做法是监听route.params.id的变化重新拉取数据watch(() route.params.id, (newId) { fetchDetail(newId) })或者干脆给 router-view 加一个:keyroute.fullPath强制每次路由变化都重新渲染组件。2.2 路由拦截器与登录态校验前后端分离的第一道门路由拦截器做的事情很简单在跳转页面之前判断用户有没有权限访问。最常见的场景就是未登录用户想进入个人中心时自动跳转到登录页。Vue Router 4 的全局前置守卫写法router.beforeEach((to, from, next) { const token localStorage.getItem(token) if (to.path /login) { next() return } if (to.meta.requiresAuth !token) { next(/login) return } next() })注意next()在上面的代码里已经返回了所以后面不会再有多余逻辑。新手常见的误区是每个分支都不 return最后next()又被执行一次造成重复导航的警告。路由元信息meta里可以配置requiresAuth、title、roles这些字段从而在守卫里做更细的权限判断。如果有“登录后回跳到原页面”的需求可以在守卫里把目标路由存一下if (!token) { next({ path: /login, query: { redirect: to.fullPath } }) }登录成功后再判断route.query.redirect有值就跳过去没有就进首页。2.3 路由懒加载与打包性能之间的平衡Vue CLI 和 Vite 都支持路由级别的代码分割。写法很简单组件引入改成动态 import// 以前 import Home from ../views/Home.vue // 现在 const Home () import(../views/Home.vue)这样打包时每个页面会被拆分成单独的 chunk首屏只加载当前页面需要的 JS大大减少初次加载时间。但也要注意别过度拆分。如果某个页面极小比如就一个简单的约 10KB 的关于页也单独拆成一个 chunk反而会增加请求数。实际情况中把基础组件和工具函数放 vendor 里按业务模块划分 chunk是性价比最高的方案。3. 状态管理Vuex 和 Pinia 到底该怎么选3.1 Pinia 比 Vuex 强在哪写 Vue 3 项目状态管理这一环大家纠结最多的就是选 Pinia 还是 Vuex 了。官方给出的态度已经很明确Pinia 是新的推荐选择。这不是说 Vuex 被抛弃了老项目继续用 Vuex 没有任何问题但新项目直接用 Pinia 就好。Pinia 的优势主要体现在几个方面Pinia 完全基于组合式 API 设计把 store 的写法强行和各种模块结构掰开写起来更像一个普通的组合式函数。Vuex 4 为了兼容 Vue 3本质上是在 Vuex 3 基础上补的类型适配设计思路还是旧的选项式风格。Pinia 没有 mutations 的概念。Vuex 里要改 state必须先定义 mutation异步操作还要再套一层 action一个简单的计数功能得写三处代码。Pinia 直接允许你在 action 里同步或异步修改 state代码量直接减半。Pinia 天然支持 TypeScript不需要像 Vuex 那样额外写一堆复杂的类型推断工具。一个简单的 Pinia Store 长这样// stores/counter.js import { defineStore } from pinia export const useCounterStore defineStore(counter, () { const count ref(0) function increment() { count.value } return { count, increment } })组件里使用import { useCounterStore } from /stores/counter const counter useCounterStore() counter.increment()完全没有mapState、mapMutations那些让人头大的辅助函数。3.2 从 Vuex 迁移到 Pinia 的平滑路径如果手头 Vuex 项目想要迁移并不需要一次性全改。Pinia 可以和 Vuex 并存两个都注册到应用里慢慢把 Vuex 的 store 一个一个迁移到 Pinia等全部迁移完再移除 Vuex 依赖。迁移时的映射关系很简单Vuex 的state- Pinia 的ref或reactiveVuex 的getters- Pinia 的computedVuex 的mutations/actions- Pinia 的function一个是 Vuex 写法的典型示例一个是 Pinia 的对应写法// Vuex 写法 mutations: { setUser(state, user) { state.user user } }, actions: { async login({ commit }, payload) { const user await api.login(payload) commit(setUser, user) } } // Pinia 写法 state: () ({ user: null }), actions: { async login(payload) { this.user await api.login(payload) } }直接这样写就行不需要 commit。这么一对比抽象成本低了很多。4. 核心功能实战m3u8 视频播放、表格导出与地图接入4.1 m3u8 视频播放方案选型与踩坑记录视频流播放是后台管理系统里比较常见的需求尤其是直播回放和教育培训类项目。m3u8 是 HLS 协议下的视频索引文件格式浏览器原生不支持直接播放需要借助 hls.js 或 video.js 这类库。推荐直接用 hls.js轻量、可控性强支持 MSE 分片播放。如果项目里已经在用 video.js也可以选择 video.js 的 contrib-hls 插件但 hls.js 的更新频率和性能表现明显更好而且和视频 UI 框架无关非常灵活。安装npm install hls.jsVue 组件中的标准接入方式template video refvideoRef controls playsinline/video /template script setup import { ref, onMounted, onBeforeUnmount } from vue import Hls from hls.js const videoRef ref(null) let hls null onMounted(() { const video videoRef.value const videoUrl https://example.com/live/master.m3u8 if (Hls.isSupported()) { hls new Hls({ enableWorker: true, lowLatencyMode: false }) hls.loadSource(videoUrl) hls.attachMedia(video) hls.on(Hls.Events.MANIFEST_PARSED, () { video.play().catch(() {}) }) } else if (video.canPlayType(application/vnd.apple.mpegurl)) { // Safari 原生支持 HLS video.src videoUrl } }) onBeforeUnmount(() { if (hls) { hls.destroy() } }) /script踩过的坑主要有几个如果直接用video.src videoUrl赋值给 video 标签在 Chrome 上基本播不了必须通过 hls.js 转成 MSE 分片数据流。hls.js 在处理多个码率时默认会自动切换码率但如果直播流不稳定频繁切换会导致花屏或卡顿。建议设置startLevel: -1配合autoStartLoad: false手动控制码率切换时机。服务端需要开启 CORS 跨域访问否则视频请求会直接被浏览器拦截。nginx 里配置add_header Access-Control-Allow-Origin *;是最省事的方案。4.2 多表格数据合并导出为一个 Excel后台管理页面里表格导出是高频需求尤其是导出时要勾选多个表格的数据。如果直接用后端接口导出通常会受数据量限制而且每张表都要新写一个导出接口。前端通过 SheetJSxlsx配合 file-saver 来做完全不吃后端资源。安装依赖npm install xlsx file-saver多表合并导出的核心思路是每个 sheet 对应一张表格的数据SheetJS 的utils.json_to_sheet可以把 JSON 数组直接转成工作表结构再通过utils.book_append_sheet加到同一个工作簿里。import * as XLSX from xlsx import { saveAs } from file-saver function exportMultipleSheets(dataList, sheetNames, fileName export.xlsx) { const wb XLSX.utils.book_new() dataList.forEach((data, index) { const ws XLSX.utils.json_to_sheet(data, { header: [id, name, createTime, status] }) // 设置每列宽度中文表头时这个细节很影响体验 ws[!cols] [{ wch: 10 }, { wch: 20 }, { wch: 24 }, { wch: 12 }] XLSX.utils.book_append_sheet(wb, ws, sheetNames[index]) }) const excelBuffer XLSX.write(wb, { bookType: xlsx, type: array }) const blob new Blob([excelBuffer], { type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet }) saveAs(blob, fileName) }坑点提醒 SheetJS 默认的中文列名没问题但如果数据结构里包含Date对象或者特殊字符导出时可能出现乱码或解析异常。稳妥做法是把所有字段先统一转成字符串再导入导出。4.3 在 Vue 里集成腾讯地图地图组件在项目里通常用于展示设备位置、配送轨迹、门店分布等。腾讯地图支持 Vue 直接通过 script 标签加载不需要额外封装成 npm 包。申请好腾讯地图开发者 key 后在index.html里引入script srchttps://map.qq.com/api/gljs?v1.expkeyYOUR_KEY/script然后在组件里初始化script setup import { ref, onMounted, onBeforeUnmount } from vue const mapContainer ref(null) let map null onMounted(() { map new window.TMap.Map(mapContainer.value, { center: new window.TMap.LatLng(39.908860, 116.397390), zoom: 12 }) // 添加标记 const marker new window.TMap.Marker({ position: new window.TMap.LatLng(39.908860, 116.397390), map: map }) }) onBeforeUnmount(() { map null }) /script template div refmapContainer stylewidth: 100%; height: 400px;/div /template注意地图容器必须有明确的宽高否则地图区域会是灰色。另外要确保初始化发生在onMounted之后因为此时 DOM 已经渲染完成容器尺寸已经计算出来了。如果使用了v-if来控制地图容器的显示务必在 DOM 真正显示后再初始化否则需要手动调用map.getContainer()或是对应地图实例的resize方法重新计算尺寸。4.4 WebSocket 推送与 vue 项目里的接入姿势WebSocket 在后台管理系统里常用于订单提醒、消息推送、协同编辑和大屏数据实时刷新。在 Vue 3 里接入 WebSocket建议封装一个全局的 socket 管理模块而不是每个页面各自 new 一个 WebSocket否则连接数会随着页面切换疯狂增长。// utils/socket.js class SocketService { constructor(url) { this.url url this.ws null } connect() { this.ws new WebSocket(this.url) this.ws.onopen () { console.log(socket connected) } this.ws.onmessage (event) { const data JSON.parse(event.data) // 根据消息类型分发到具体页面 this.handleMessage(data) } this.ws.onclose () { // 断线重连 setTimeout(() this.connect(), 3000) } } handleMessage(data) { // 用事件总线或 pinia 进行状态更新 } } export default new SocketService()像这种长时间连接的功能断线重连是必须做的。在onclose里加延时重连同时注意心跳机制每 30 秒发送一次自定义心跳包服务端收到后返回 pong如果连续几次收不到 pong 就主动断开重建连接避免“假连接”导致推送丢失。5. 前后端分离协作Token 处理、跨域与部署5.1 请求封装与 axios 拦截器里 token 的完整处理Spring Boot Vue 前后端分离已经是目前最普遍的团队协作模式。Vue 负责页面渲染和交互Spring Boot 只提供 RESTful API。两者之间通过 HTTP 请求通信这个过程中 Token 处理是最容易出问题的环节。Token 的存储位置我推荐放localStorage。虽然有些安全团队建议放内存变量但刷新页面会丢失需要重新登录实际体验不好。localStorage 的 XSS 风险可以通过内容安全策略CSP和输入校验来缓解算是便利性和安全性的一个折中方案。封装 axios 时的核心逻辑// utils/request.js import axios from axios import router from /router const service axios.create({ baseURL: /api, timeout: 10000 }) // 请求拦截器附加 token service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers.Authorization Bearer ${token} } return config }, error Promise.reject(error)) // 响应拦截器统一处理错误码和 token 过期 service.interceptors.response.use( response { const res response.data if (res.code ! 0) { // 业务错误统一弹提示 return Promise.reject(new Error(res.message)) } return res.data }, error { if (error.response?.status 401) { localStorage.removeItem(token) router.push(/login) } return Promise.reject(error) } )一个关键点是token 过期返回 401 后的处理逻辑。简单跳转登录页是最初级的做法。实际项目里遇到这种情况可以考虑在请求拦截器里做“单点故障升级”处理即用一个isRefreshing标识把并发请求都挂起先刷新 token再重新发请求。这样一个 token 过期不会导致多个请求同时跳到登录页用户体验会好很多。5.2 Vite 和 Nginx 的跨域配置开发环境下的跨域问题Vite 通过 proxy 就能解决。在vite.config.js里配置export default defineConfig({ server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, // 如果需要后端接口路径不带 /api可以重写 rewrite: path path.replace(/^\/api/, ) } } } })这样配置后前端请求/api/login开发服务器会把它转发到http://localhost:8080/login同时changeOrigin: true会把请求头里的 Host 改成目标地址后端不会出现跨域问题。生产环境的跨域主要交给 Nginx 处理location /api/ { proxy_pass http://localhost:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }5.3 打包后布局异常的排查思路打包后布局异常是一个很经典的问题特别是 Vue 项目部署到服务器上刷新页面以后 404或者样式一加载就错乱CSS 引用路径完全不对。主要原因通常有三个源码里用了绝对路径引用静态资源。Vue CLI 打包后 index.html 引用 CSS/JS 的路径默认是/js/app.xxx.js如果项目部署在子目录比如http://example.com/admin/这个/js/...会直接指向域名根目录资源自然找不到。解决方法是在vue.config.js里配置publicPath: ./用相对路径或者在构建部署时通过--base./指定。Vite 项目则需要在vite.config.js里设置export default defineConfig({ base: ./ })另一个是前端路由用了 history 模式Nginx 没有配置try_files刷新某个页面时 Nginx 按照路径去找文件找不到直接返回 404。Nginx 配置如下location / { try_files $uri $uri/ /index.html; }把路由交给index.html让前端路由接管刷新页面就能正常加载了。布局乱还有一种情况是路由切换正常但刷新后页面错位多是因为某些 JS 在组件挂载前就尝试操作 DOM导致初始化时序不对。排查时先打开浏览器控制台看有没有报错再按 Network 面板里的请求顺序确认资源是否全部加载成功。6. 项目实战方向从开源脚手架到毕业设计的思路6.1 若依RuoYi这类 Vue 开源框架怎么在 IDEA 里跑起来前几天还有人问我“若依这种开源项目怎么在 IDEA 里部署”这个框架在中小企业里的普及率确实高。它的结构是 Spring Boot 做后端 Vue 做前端两个工程独立运行通过接口交互。在 IDEA 里同时启动前后端项目核心就三步后端工程导入 IDEA配置好 Maven 仓库路径等待依赖下载完成。然后修改application-druid.yml里的数据库连接信息把 MySQL 和 Redis 都启动起来直接运行RuoYiApplication.java主类。前端工程用 IDEA 内置的终端执行npm install npm run dev因为前后端端口不同需要在vue.config.js里配置 devServer 的 proxy 把请求转发到后端端口。有一个小坑需要留意若依的本地开发默认端口是 8080如果会和前端 Vite 的代理目标端口冲突可以在配置文件里改后端的 server.port或者在前端 proxy 里改 target 端口保持一致即可。这类开源脚手架的优点是大量通用功能用户管理、部门管理、菜单管理、代码生成开箱即用适合企业内部项目快速启动。但要注意版权协议和二次开发规范改代码时尽量保持原有分层避免后续升级依赖困难。6.2 适合做毕业设计的 Vue 项目选题与注意点如果是学生朋友做毕业设计基于 Spring Boot Vue 的选题非常多在线点餐系统、流浪动物领养管理系统、图书借阅系统、班级数据分析平台、校园二手交易平台……选题上我建议避开两个极端所有同学都做的重复度太高的和完全没有实际使用场景的。第三方评审时更看重的是“你做的东西解决了什么实际问题”。比如“流浪动物领养管理系统”比“基于 Vue 的通用后台管理系统”更容易讲清楚需求来源和业务价值。技术选型上前端 Vue 3 Element Plus Pinia Axios 是最稳妥的一套组合后端 Spring Boot MyBatis-Plus MySQL 可以快速把 CRUD 写完。如果想要答辩时有一点亮点可以加一个 WebSocket 做实时通知或者接入 hls.js 做宠物领养视频展示这一加分项在论文里也很容易展开写作。论文系统设计和实现部分建议画清楚架构图和 E-R 图代码不一定要多么炫酷只要逻辑清晰、注释清楚、核心功能能跑通答辩环节基本不会出大问题。6.3 django vue 这类跨技术栈组合的实践价值有人用 FastAPI Vue有人用 Django Vue还有人用 Spring Boot Vue。前端统一是 Vue差异在后端技术栈。这类跨技术栈项目最大的价值在于锻炼“约定优于配置”的能力后端返回什么数据结构前端如何与之对齐接口文档怎么维护这些在实际工作中比具体用哪个框架更重要。拿 FastAPI Vue 来说FastAPI 自动生成的 Swagger 文档接口调试非常方便。前后端联调时前端同学可以直接对着文档看字段类型省去翻代码的麻烦。跨技术栈协作时有一个高频冲突点后端返回的时间字段格式、字段命名风格下划线还是驼峰不统一。建议在项目启动时就把接口规范定好统一返回{ code, message, data }结构时间统一用时间戳或YYYY-MM-DD HH:mm:ss字段名后端统一转成驼峰前端拿到就能直接用。7. 调试工具与日常效率提升7.1 Vue Devtools 插件的安装与常见问题Vue Devtools 是调试 Vue 项目的必备插件它可以查看组件树、路由信息、Pinia/Vuex 的实时状态、事件触发记录比手动 console.log 的效率高得多。Chrome 应用商店直接搜索 Vue.js devtools 安装即可。插件安装后打开 Vue 项目页面地址栏右侧的图标会从灰色变成 Vue 的绿色打开开发者工具能看到 Vue 面板。常见问题有两个插件装上了但图标是灰色说明当前页面不是 Vue 项目或者项目没有以开发模式运行生产构建会禁用 devtools另一个是项目里开了严格模式和插件冲突可以在控制台手动引入独立的 devtools 脚本解决。Firefox 和 Edge 也有对应的 Vue Devtools 版本用法一致。7.2 Vite 构建时的 ignonred build scripts 报错怎么办执行npm install时有时候会看到这样的提示ignored build scripts: esbuild0.21.5这不是安装失败了而是 npm 基于安全策略拦下了依赖里的构建脚本。esbuild 的 postinstall 脚本会在安装时把原生的二进制文件下载到位。如果被忽略后面npm run dev启动时 esbuild 可能会报缺少二进制。解决办法是在项目根目录建一个.npmrc写入esbuild: true或者用命令强制重新构建npm rebuild esbuild这样 esbuild 的二进制就补回来了。如果还不行直接删掉 node_modules 和 package-lock.json 重新安装一次基本都能解决。7.3 vue ui 自动断开问题的排查方向Vue CLI 自带的图形化管理界面vue ui在部分环境下会出现连接自动断开的情况。常见原因一般是端口被占用或者浏览器有缓存导致本地服务通信中断。排查时可以先用命令行查看端口状态确认vue ui的默认端口 8000 没有被别的程序占用。换一个端口试试vue ui --port 8088如果断开的频率还是很高考虑是不是浏览器插件的问题用无痕模式打开http://localhost:8088再测试。8. 常见面试题串讲Vue 老一辈和新一代的问题都有收集到的热词里有“vue面试题”这块我也顺手整理一下。面试官问 Vue 相关的问题翻来覆去其实就是那几类响应式原理、生命周期、组件通信、虚拟 DOM、diff 算法、Vue 2 到 Vue 3 的差异。Vue 3 的响应式基于 Proxy而不是 Vue 2 的 Object.defineProperty。Proxy 可以直接监听对象属性的新增和删除所以 Vue 3 里不再需要用$set来给对象添加属性数组的索引操作也能被正常响应。组件通信方式父传子用 props子传父用 emit 或 v-model跨层级用 provide/inject通用状态用 Pinia复杂场景可以在组件实例上挂载 mitt 事件总线。生命周期变化也是常考的点beforeDestroy变成了beforeUnmountdestroyed变成了unmounted新增了onMounted、onUpdated、onBeforeUnmount这些组合式 API 写法。还有一个坑是onMounted的执行顺序子组件先于父组件先设好子组件的数据父组件才能拿到正确状态。Vue 2 和 Vue 3 的 diff 算法差异面试官偶尔会深挖。Vue 3 的虚拟 DOM 对动态节点做了 patch flag 标记可以跳过静态节点的对比性能提升比较明显。如果是偏向日常业务的岗位面试官还会问路由守卫、Axios 拦截器、权限控制、keep-alive 组件缓存这类的实操内容。能把这些功能和项目场景结合讲清楚比背概念更有说服力。9. 组件化开发与工程化进阶9.1 Composable 组合式函数把逻辑抽出来复用Vue 3 的 Composable组合式函数解决了 Vue 2 时代 Mixin 的杂乱问题。Mixin 的缺点很明显变量来源不透明、多个 mixin 可能有命名冲突、跨项目复用困难。Composable 就是普通函数只是在内部可以使用ref、reactive、computed、watch这些 Vue API。按需提取一段可复用的逻辑返回给组件使用。举一个实际例子滚动加载下一页数据// composables/useInfiniteScroll.js import { ref, onMounted, onBeforeUnmount } from vue export function useInfiniteScroll(loadMore) { const loading ref(false) const hasMore ref(true) function onScroll() { if (loading.value || !hasMore.value) return const distanceToBottom document.documentElement.scrollHeight - window.innerHeight - window.scrollY if (distanceToBottom 100) { loading.value true loadMore().finally(() { loading.value false }) } } onMounted(() window.addEventListener(scroll, onScroll)) onBeforeUnmount(() window.removeEventListener(scroll, onScroll)) return { loading, hasMore } }组件里调用const { loading, hasMore } useInfiniteScroll(fetchNextPage)逻辑被完整封装起来组件模板里只关心渲染维护成本低很多。9.2 v-model 在自定义组件里的正确姿势Vue 3 的 v-model 在自定义组件上的默认值从value改成了modelValue这让组件双向绑定的语义更清晰。以前写自定义输入框组件template input :valuemodelValue input$emit(update:modelValue, $event.target.value) / /template script setup defineProps([modelValue]) defineEmits([update:modelValue]) /script在父组件里直接用v-modelkeyword就实现了双向绑定。v-model 还支持多个绑定值比如一个弹窗组件同时需要控制显示状态和一些操作结果Dialog v-model:visibledialogVisible v-model:titledialogTitle /这个用法在做表单类组件、弹窗类组件、抽屉类组件时非常实用比传一堆 props 再用事件回调的方式省心得多。9.3 ant-design-vue 这类 UI 库引入时的主题定制经验Ant Design Vue 是目前 Vue 3 生态里企业级组件库一个可靠选项。安装npm install ant-design-vue4.x如果要定制主题色可以在 Vite 项目里用 CSS 变量覆盖:root { --ant-primary-color: #1890ff; /* 自定义主色 */ }组件库默认样式不满足需求时不要直接去改 node_modules 里的源码正确的做法是全局覆盖样式类或者用 CSS Modules 给组件包裹一层自己的类名进行样式隔离。还有一个实用技巧按需引入组件可以减少打包体积。安装unplugin-vue-components和unplugin-auto-import这两个 Vite 插件后组件可以自动按需加载同时在模板里使用a-button这类前缀的组件时不需要手动注册。配合 ant-design-vue 的图标打包后体积能明显减小。9.4 多表格导出一个 Excel 的升级版样式美化前面写过多 sheet 导出的基础方法如果再进阶一步需要在导出的 Excel 里带上标题行、合并单元格和颜色样式。SheetJS 的能力偏基础真正完整的样式需要借助exceljs这个库。npm install exceljs用 exceljs 创建带样式的表头import ExcelJS from exceljs const workbook new ExcelJS.Workbook() const sheet workbook.addWorksheet(Sheet1) sheet.columns [ { header: ID, key: id, width: 10 }, { header: 姓名, key: name, width: 20 }, { header: 创建时间, key: createTime, width: 24 } ] sheet.getRow(1).font { bold: true, color: { argb: FFFFFF } } sheet.getRow(1).fill { type: pattern, pattern: solid, fgColor: { argb: 4472C4 } }exceljs 支持合并单元格、边框、条件格式、公式、图片做财务报表导出时性能也稳定推荐在复杂场景下直接用。10. 一点个人经验总结关于整个 Vue 生态的学习路径写到这里再回头看你搜到的那一串关键词其实它们已经悄悄把 Vue 学习路径画出来了。先装环境nodejs 安装、依赖安装、vscode 配置然后把 Vue 项目跑起来接着了解模板语法和响应式进入项目之后配合路由和后端做完整应用组件化思维在这个过程中自然被锻炼出来。真正把多个技术点串联起来的关键是动手做一个完整的项目而不是只看教程。我在实际使用中发现把 m3u8 播放、Excel 导出、地图标记、WebSocket 推送这些都塞进同一个 demo 项目里跑通一遍以后面试时不管被问到哪一块心里都有底。最后再分享一个小技巧Vue 的报错信息其实写得非常有条理遇到问题先别慌把控制台红字按顺序读一遍八成问题就出在离报错位置最近的上一次操作上。这个习惯能帮你节省大量查错时间。
返回列表