ARTICLE DETAIL

资讯详情

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

Vue Router实战:从路由基础到Spring Boot部署

Vue Router实战:从路由基础到Spring Boot部署 今天是咱们一起啃 Vue 的第七天。先说个定位如果你前六天已经能把模板语法、组件通信、指令、事件绑定这些基础玩得差不多那今天就是让你从“会写组件”真正跨到“会搭页面”的关键一天。这个坎叫路由。很多小白卡在这里不是学不会而是不知道精力该往哪放——Vue Router 的 API 多到查不完一会儿看动态路由一会儿看嵌套路由再翻翻路由守卫直接把自己绕晕。我帮你把今天的范围圈死只学五件事——router-view、router-link、push、路由参数、嵌套路由。最后一节再塞一个特别实战的场景把打包好的 Vue 项目塞进 Spring Boot 后端里去跑。这一套学完你就能独立做出一个带导航栏的多页面小站而且是能真正跑起来、能发给别人看的那种。顺便说一句各大社区里搜“vue 入门”“vue 路由”“vue 项目实战”的人特别多但大部分教程要么太散要么直接上企业级方案。今天我尽量用大白话按一个新人第七天该有的节奏来讲每段代码你都跟着敲一遍动手就是最快的理解方式。1. 先搭一个带路由的项目好多人在第六天还在用“单文件组件 一个 App.vue 打天下”的方式写 demo这没什么问题。但只要你开始做多页面的东西就绕不开路由。所谓路由说白了就是 URL 和页面组件的对应关系地址栏是 /home就显示首页组件地址栏是 /about就显示关于页组件。在没有路由的年代你得手动维护一堆显示/隐藏的布尔变量页面一多代码直接爆炸。1.1 为什么第七天才碰路由你可能会问为什么不是第一天就学路由因为路由依赖组件组件依赖响应式数据响应式数据依赖模板语法。前面几天没把地基打好今天一上路由你会把“组件不显示”“路由跳了但内容没变”“参数拿不到”这些锅全部甩给路由其实全是基础概念不牢。第七天这个时间点刚刚好你已经知道一个 .vue 文件长什么样知道父组件怎么引用子组件也知道点击事件、动态绑定这些基础操作。路由对我来说只是把这些知识重新组装一下并没有引入什么天外来客。所以今天不要慌内容看起来多但每个知识点都不难。1.2 用 Vite 创建一个干净项目我默认你的电脑上已经装好了 Node.js版本最好在 16 以上。咱们用 Vite 而不是 Vue CLI原因很简单Vite 启动快配置文件直观而且现在脚手架默认推荐就是它。打开终端执行npm create vitelatest vue-day7 -- --template vue跑完以后进目录、装依赖cd vue-day7 npm install这时候你得到一个干净的 Vue 3 项目。接着安装 Vue Router注意是 Vue 3 对应 Router 4别装成 vue-router3那是给 Vue 2 用的npm install vue-router4有个小细节说一下如果你用npm install vue-router不指定版本默认装到 4.x但有些人公司的镜像源比较旧可能给你解析出 3.x到时候一运行就报奇怪的错误。稳妥起见加4最保险。1.3 初始化路由的规范写法安装完路由以后在src目录下新建一个router文件夹里面建index.js。官方推荐把所有路由配置集中在这里项目大了以后方便维护。// src/router/index.js import { createRouter, createWebHistory } from vue-router import Home from ../views/Home.vue import About from ../views/About.vue const routes [ { path: /, name: home, component: Home }, { path: /about, name: about, component: About } ] const router createRouter({ history: createWebHistory(), routes }) export default router然后去main.js里注册import { createApp } from vue import App from ./App.vue import router from ./router createApp(App).use(router).mount(#app)这里我必须多嘴一句createWebHistory()依赖后端配合否则你部署到静态服务器上刷新某个子路径会 404。新手阶段完全可以用createWebHashHistory()地址栏会多一个#但好处是随便刷新都不会 404。后面我们讲部署的时候再展开现在先记住有这个区别。2. 路由的核心两件套router-view 和 router-link很多人学路由会先去看useRouter()、useRoute()这些组合式 API其实对新手来说先搞懂两个模板组件才是关键router-view负责“页面内容往哪显示”router-link负责“点击之后怎么跳”。这两个词贯穿 Vue Router 的整个使用过程比任何 API 都重要。2.1 router-view页面内容的“出风口”router-view是一个占位组件。你可以把它想成客厅墙上的一个画框路由匹配到什么组件就把什么组件放进画框里。它本身不负责渲染任何东西只是一个出口。修改你的App.vue把默认模板全部清掉只留这个template router-view / /template这时候访问/你会看到 Home 组件内容访问/about画框里就换成 About 组件。这就是整个 Vue 单页应用最核心的机制页面不是真正地跳转去请求一个新的 HTML而是 JS 动态地把对应组件插入到router-view这个位置。有个非常常见的误区新手以为router-view只能写一个其实它可以有多个配合命名视图使用。但今天我先不展开你想快速上手的话先记住“一个路由对应一个router-view”就够用了。2.2 router-link为什么不用 a 标签很多新手会问跳转我用a href/about不就行了行但会有一个坑原生a标签点击后会向服务器发起一个完整请求然后重新加载整个页面这违背了单页应用的初衷还会让页面闪烁一下。router-link做的事情是拦截点击直接用 JS 改变路由状态不触发整页刷新。最直观的写法nav router-link to/首页/router-link router-link to/about关于/router-link /navto属性除了写字符串还可以传对象router-link :to{ name: about }关于/router-link用name的好处是如果你的路径改了只要路由名不变页面里的所有跳转都不用动。这个习惯从第一天就养成后期维护会轻松很多。2.3 做一个能切换的导航首页咱们把两件套拼起来做一个最基础的双页导航template div classlayout nav router-link to/首页/router-link router-link to/about关于/router-link /nav router-view / /div /template启动开发服务器npm run dev然后点击导航你会发现地址栏变了页面内容也变了但页面没有整个刷新。这就是单页应用的核心体验。到这一步你的第一个“多页面项目”就成型了。不要小看这个 demo后面所有复杂路由包括权限控制、动态路由都是在这两行代码的基础上叠加出来的。3. 页面跳转和参数传递push、query 与动态路由导航栏用router-link就够了但实际业务里更多时候是点击某个按钮、某个列表项之后才跳转。这时候要写 JS 代码用useRouter()的push方法。传参则有两种主流方式query 字符串和动态路径参数。这两个概念天天出现在面经里今天必须理清。3.1 编程式跳转useRouter().push()先引入script setup import { useRouter } from vue-router const router useRouter() function goAbout() { router.push(/about) } /scriptpush的意义是“把一条新记录压入历史栈”所以用户点浏览器的返回按钮可以回到上一个页面。如果你不想留下历史记录用replacerouter.replace(/about)这个场景最常见的应用是登录成功之后跳转到首页。你肯定不希望用户点返回还能回到登录页这时用replace更合理。3.2 传参的两种常见姿势Query 方式适合传一些查询条件、搜索关键词URL 上会带?问号router.push({ path: /about, query: { id: 123, name: vue } })跳转过去之后目标页面接收script setup import { useRoute } from vue-router const route useRoute() console.log(route.query.id) // 123 console.log(route.query.name) // vue /script这种方式简单直观你也看得见地址栏里的参数刷新页面参数也不会丢。缺点就是 URL 会比较长不适合传特别敏感的数据。另一种方式是动态路由匹配路由配置里用冒号定义参数占位{ path: /user/:id, name: user, component: User }跳转的时候router.push({ name: user, params: { id: 7 } })地址栏会变成/user/7目标页面用route.params.id拿到 7。这两种方式的本质区别一个是参数挂在?后面一个是参数嵌在路径里。前者对路由配置没有要求后者必须提前在路由表里声明好:id这样的占位符。新手经常在这栽跟头用params传参但路由表里没有这个参数结果目标页面拿到的全是undefined。3.3 动态路由的典型应用详情页动态路由最常见的就是资讯详情、商品详情这类页面——列表页只要显示标题和摘要点击一条就跳到对应的详情页URL 带上对应的 ID。实现思路是这样的列表页循环输出数据给每一项绑定点击事件li v-foritem in list :keyitem.id clickgoDetail(item.id) {{ item.title }} /lifunction goDetail(id) { router.push({ name: article, params: { id } }) }路由表{ path: /article/:id, name: article, component: Article }详情页拿到 id 之后就可以拿着这个 id 去请求接口。这就是一个标准的前后端分离详情页流程。面试官问你动态路由是干嘛的你举这个例子他就知道你见过真实项目。还有一个细节同一个动态路由比如从/article/1切到/article/2组件不会重新挂载只会触发参数更新。如果详情页要根据 id 刷新数据需要用watch监听route.params.id的变化。这个坑非常经典先记下来等你自己写列表页跳详情的时候一定会遇到。4. 嵌套路由与插槽让布局真正活起来到这一步单层路由你已经很熟了。但真实后台管理系统很少只有一层页面比如一个“用户管理”模块下面还分用户列表、用户详情、用户编辑。这种“页面里面套页面”的结构必须用嵌套路由。同时如果你接触布局组件会发现插槽在这个阶段开始变得非常有用。4.1 children嵌套路由的正确打开方式嵌套路由就是在父路由的配置里增加一个children数组子路由的path前面不要加/不然会被当成顶级路径const routes [ { path: /user, component: UserLayout, children: [ { path: , component: UserList }, { path: detail/:id, component: UserDetail } ] } ]UserLayout这个组件里需要放一个router-view /子路由匹配到的组件会渲染在这个位置。注意子路由的path是相对路径不用带父级路径。所以访问/user/detail/7的时候先加载UserLayout再在其router-view里加载UserDetail。这种结构非常灵活你做后台管理系统时左侧菜单是固定的布局组件右侧主内容区就是一个router-view。左侧点击菜单右侧切换页面。这就是几乎所有后台系统的骨架。4.2 插槽在布局里的妙用插槽slot和路由是两件事但它们经常一起出现在布局组件里。比如你做UserLayout时顶部一个导航栏底部一个内容区中间可能还想给操作按钮留一个自定义区域这时候具名插槽就派上用场了template div header用户中心/header main router-view / /main footer slot namefooter默认底部/slot /footer /div /template使用这个布局的页面可以自定义底部内容UserLayout template #footer button自定义操作按钮/button /template /UserLayout对小白来说先把默认插槽和具名插槽的区别搞明白就足够了。插槽的本质是“父组件往子组件里塞内容”当你发现一个组件中间某块区域需要留给外部自定义时就该用插槽。这个感觉找对了后面看任何 UI 组件库的实现都不会太吃力。4.3 样式冲突和路由切换的“暗坑”写组件多了以后你会发现一个现象在组件 A 里定义的样式莫名其妙影响到组件 B。多半是因为你用的是普通style没有加scoped。加上scoped以后Vue 会给当前组件的所有 DOM 元素加一个特殊的>style scoped .nav { background: #333; } /style这个习惯最好从今天就养成——每个组件的样式都写上scoped除非你明确知道这个样式是全局的。另外路由切换时偶尔会出现页面样式短暂错乱多半是全局样式中用了固定的类名但组件没来得及加载干净。这种问题排查起来费劲但只要你全局 CSS 命名规范一些别全用.box.title这种烂大街的类名就能避开大半。5. 新手高频报错实战排查写任何技术代码不出错是不可能的重点是你知不知道去哪找原因。我挑了几个高频问题都是第七天学员最容易踩的坑直接按实战排查的方式来写。5.1 白屏和 404先分清阶段白屏一般分三种第一种是页面完全空白控制台也不报错多半是router-view忘了写或者写错位置了第二种是控制台报错Cannot read properties of undefined这种往往是组件里访问了不存在的对象属性第三种是地址栏路径变了但页面空白的先刷新一下如果刷新好了那大概率是 history 模式的问题。404 就更典型了。开发环境基本遇不到一部署到 Nginx 或者静态服务器上你访问/about刷新服务器找不到这个目录就返回 404。原因就是我开头说的createWebHistory()是 HTML5 history 模式路径是真实的 URL 路径静态服务器没有做回退处理。新手最省事的办法就是改用 hash 模式history: createWebHashHistory()如果你非要坚持 history 模式那部署的时候必须给服务器配置正确的 fallback 规则。这个属于部署层面的问题今天先不展开太多你记住“刷新 404先怀疑 history 模式”就够了。5.2 failed to load tsconfig模板工程自带的坑很多新手按照网上的教程创建 Vite Vue TS 项目一路默认下来运行后突然报错failed to load tsconfig vue/tsconfig/tsconfig.web.json: tsconfig not found这个错不是你代码写错了而是工程模板里引用了vue/tsconfig这个包但依赖没有装全。解决办法很直接npm install -D vue/tsconfig装完再跑问题就消失了。这个问题在社区热词里经常出现也侧面说明很多人直接npm create vuelatest创建项目后马上启动忽略了依赖安装完整性。遇到这类报错先别慌着搜“代码哪里写错”先检查依赖包是不是存在。5.3 参数拿到 undefined 和浏览器兼容问题传参拿不到最常见的两种情况第一你用route.params.id但路由表里没有定义:id第二你用route.query.id但跳转时写的是params。字段名错了自然拿不到。教你一个排查口诀先看地址栏地址栏里有没有参数有参数再看代码里取的名字对不对。还有个冷门但真实存在的坑Vue 开发环境下和 Edge 浏览器偶发兼容问题。表现是页面能加载但点击router-link不跳转或者控制台在某个文件上卡住。你先检查一下是不是 Edge 的某个扩展拦截了比如装了翻译插件或者广告拦截器再不行就裸奔模式测试。这问题十次里九次是插件干扰不是代码问题不需要改代码。5.4 样式覆盖和组件显示顺序怪异还有一种让人崩溃的情况页面显示顺序不对比如导航栏跑到内容下面去了检查 CSS 的 float、position 和 z-index。新手经常在全局 CSS 里写了flex或position: absolute然后每个组件又用scoped样式去微调结果局部样式优先级不够直接被全局压住。这种问题排查起来比较费眼力建议全局样式尽量只写 reset 和公共变量具体的布局样式放在各自组件里写。6. 打包部署与源码交付今天就能用上的实战学到这里你的小项目已经能跑了。但“能跑”和“能发给别人看”之间还差一个打包部署。这一节我把热词里反复出现的“vue打包放进springboot中”和“vue项目源码怎么发给别人”一次性讲清楚。6.1 打包前的路径设置默认情况下Vite 打包出来的资源路径是绝对路径/assets/xxx。如果你的项目部署在服务器根目录没问题但如果部署在某个子路径下比如http://localhost:8080/admin/那所有资源都会找不到。解决办法是在vite.config.js里设置baseexport default { base: ./ }改成相对路径之后打包出来的 index.html 引用的就是./assets/xxx这样不管你把静态文件放在哪个目录下都能正常打开。新手最容易忽略的就是这个base配置一堆人打包完直接双击 index.html 看效果结果白屏就是路径不对。另外提醒一句如果你用了 history 模式的路由双击本地 index.html 仍然会白屏因为二级页面是 JS 模拟的直接打开文件没法模拟。这也是为什么我一直建议新手先用 hash 模式。6.2 把打包结果放进 Spring Boot很多人的毕业设计或者公司内部项目是 Spring Boot 后端 Vue 前端的组合。你要做的是先打包 Vue 项目npm run build打包完成后dist目录下会有一个index.html和assets文件夹。把这个目录里的所有文件复制到 Spring Boot 的src/main/resources/static目录下然后重新启动后端。之后你访问后端的根路径看到的就是 Vue 应用。有个小坑如果你的后端接口全部走/api开头那前端打包后不存在跨域问题因为页面和后端是同源的。但如果接口路径不对你就要在前后端协调一下。另外一个常见的坑是Spring Boot 默认会处理/error路径如果你的 Vue 路由里有/error这个地址可能会冲突。部署完之后再用 hash 模式刷新测试一下基本不会出问题。这一套流程亲自走一遍你对“前端项目怎么部署到服务器”这件事就有切身感受了后面不管是放到云服务器还是打包成 Docker 镜像都是在这个基础上扩展。6.3 源码发给别人的正确姿势最后说一下“vue项目源码怎么发给别人”。很多人直接用微信传整个项目文件夹结果对方打开发现node_modules是空的或者传了两天才传完。正确做法是把源代码放到 Git 仓库里node_modules通过.gitignore排除掉别人拿到后只需要执行npm install就能装齐所有依赖。如果你不想用 Git那至少把node_modules删掉再压缩发送对方收到后也要先执行npm install。记住一个原则源码里永远不要包含node_modules它只是安装出来的依赖产物不是你的代码。另外一个进阶点的建议如果对方不会命令行你可以把项目部署到一个免费静态托管平台上直接把线上链接发过去。这样对方连环境都不用配点开就能看到效果。走到这一步你的 Vue 学习就真正从“本地自嗨”进入“可交付”阶段了。我在实际项目里带过很多新人第七天这个节点最明显的分水岭就是有的人还在改昨天的 demo有的人已经能独立搭出带登录页、列表页、详情页的小系统了。差别不在智商就在于有没有在一个干净的项目里老老实实把路由这套流程走一遍。路由说白了就两个组件加一个方法真正拦路的是那些没人告诉你的细节——版本、路径、参数名、部署回退。今天这篇把这些坑都填了一遍剩下的就是你自己动手去敲。后面如果你要深入后台管理系统可以考虑动态路由和路由守卫但那是另一篇的故事了。
返回列表