一、前言最近在学习 Vue3 的路由部分为了把知识点真正串起来我自己做了一个小项目。这个项目虽然不大但是把 Vue3 路由中很多核心内容都练到了包括基础路由切换默认重定向router-link和router-viewquery传参params传参编程式导航router.push()嵌套路由children相比单独去记一个个零散 API我更喜欢通过一个完整的小案例来理解。因为这样更接近真实项目开发场景也更容易形成整体思路。二、项目最终实现了什么这个项目最终实现了下面这些功能1. 顶部基础导航可以在下面几个页面之间切换首页新闻页关于页用户中心2. 新闻页新闻页中有一个新闻列表每条新闻都可以使用query方式跳转详情页使用params方式跳转详情页使用按钮进行编程式导航跳转3. 用户中心用户中心里又包含两个子页面我的消息我的资料这部分通过嵌套路由实现。所以这个项目虽然是练习项目但它已经具备了“小而全”的特点适合用来系统理解 Vue3 路由。三、项目结构设计我的项目大致结构如下src ├── router │ └── index.js ├── views │ ├── HomeView.vue │ ├── NewsView.vue │ ├── AboutView.vue │ ├── NewsDetail.vue │ ├── NewsDetail2.vue │ ├── UserView.vue │ ├── MessageView.vue │ └── ProfileView.vue ├── App.vue └── main.js这里我把页面级组件放在views文件夹中把路由配置放在router/index.js中这也是 Vue 项目里比较常见的组织方式。四、先理解路由的本质在正式看代码之前先明确一个核心概念路由的本质就是路径和组件的映射关系。比如/home对应首页组件/news对应新闻组件/about对应关于组件/user对应用户中心组件也就是说当浏览器地址变化时Vue Router 会根据路径找到对应的组件然后渲染到页面上。所以路由不是单纯“点一下换个页面”而是不同的 URL 路径对应不同的组件内容。五、路由配置文件详解项目中最核心的文件之一就是src/router/index.jsimport { createRouter, createWebHistory } from vue-router import Home from ../views/HomeView.vue import News from ../views/NewsView.vue import About from ../views/AboutView.vue import NewsDetail from ../views/NewsDetail.vue import NewsDetail2 from ../views/NewsDetail2.vue import User from ../views/UserView.vue import Message from ../views/MessageView.vue import Profile from ../views/ProfileView.vue const router createRouter({ history: createWebHistory(), routes: [ { path: /, redirect: /home }, { path: /home, component: Home }, { path: /news, component: News }, { path: /about, component: About }, { path: /newsDetail, component: NewsDetail }, { path: /newsDetail2/:id/:title, name: detail2, component: NewsDetail2 }, { path: /user, component: User, children: [ { path: message, component: Message }, { path: profile, component: Profile } ] } ] }) export default router1.createRouter()的作用import { createRouter, createWebHistory } from vue-router这里导入了 Vue Router 中两个最重要的方法。其中createRouter()用于创建路由器对象。你可以把它理解成整个项目的“路由管理中心”。2.createWebHistory()的作用history: createWebHistory()表示项目使用history 模式。这样地址看起来会比较干净例如/home /news /about而不是带#的形式。3.routes是什么routes是一个数组里面的每一项都是一条路由规则。例如{ path: /home, component: Home }表示当路径是/home页面显示HomeView.vue所以这本质上就是在配置路径 → 组件4. 默认重定向redirect{ path: /, redirect: /home }这条配置表示当访问根路径/自动跳转到/home这样用户一打开项目就会默认进入首页而不会看到空白页面。5.query详情页路由{ path: /newsDetail, component: NewsDetail }这个路由配合query传参使用。例如最终地址可能是/newsDetail?id1titleVue3路由基础路径本身还是/newsDetail只是后面额外带上了 query 参数。6.params详情页路由{ path: /newsDetail2/:id/:title, name: detail2, component: NewsDetail2 }这里的:id:title就是动态参数。也就是说这条路由不是固定的一个字符串路径而是会根据传入的数据动态变化。例如可能变成/newsDetail2/1/Vue3路由基础这里还加了一个name: detail2这是命名路由方便后面用params方式跳转。7. 嵌套路由children{ path: /user, component: User, children: [ { path: message, component: Message }, { path: profile, component: Profile } ] }这部分是嵌套路由。它表示/user显示UserView.vue/user/message显示MessageView.vue/user/profile显示ProfileView.vue这其实就是“一个页面里面再切换子页面”的典型场景。六、为什么main.js一定要注册路由来看main.jsimport { createApp } from vue import App from ./App.vue import router from ./router createApp(App).use(router).mount(#app)这里最关键的一句是.use(router)它的作用是把路由功能安装到 Vue 应用中。如果不写这一句项目中这些功能都不能正常使用router-linkrouter-viewuseRouter()useRoute()所以一定要记住路由不是光写配置文件就行了还必须在main.js中注册。七、App.vue路由入口页面项目中的App.vue如下template div h1Vue3 路由小案例/h1 router-link to/home首页/router-link | router-link to/news新闻/router-link | router-link to/about关于/router-link | router-link to/user用户中心/router-link hr / router-view / /div /template style scoped a { margin-right: 10px; text-decoration: none; color: black; } .router-link-active { color: red; font-weight: bold; } /style1.router-link的作用router-link用于跳转路由。例如router-link to/news新闻/router-link表示点击后跳转到/news。它相当于 Vue Router 提供的专用导航链接。2.router-view的作用router-view /这是路由出口。作用是显示当前路径匹配到的组件。例如当前路径是/home这里显示首页组件当前路径是/news这里显示新闻页组件当前路径是/user这里显示用户中心组件可以把它简单记成router-link负责跳转router-view负责显示3. 路由高亮是怎么实现的当前激活的链接会自动带上类名.router-link-active所以我在样式里写了.router-link-active { color: red; font-weight: bold; }这样当前页面对应的导航链接就会高亮。八、新闻页综合使用 query、params 和编程式导航新闻页代码如下template div h2新闻页/h2 ul li v-foritem in newsList :keyitem.id span{{ item.title }}/span !-- query传参 -- router-link :to{ path: /newsDetail, query: { id: item.id, title: item.title } } 查看详情(query) /router-link !-- params传参 -- router-link :to{ name: detail2, params: { id: item.id, title: item.title } } 查看详情(params) /router-link !-- 按钮编程式跳转 -- button clickgoDetail(item)按钮跳转/button /li /ul /div /template script setup import { ref } from vue import { useRouter } from vue-router const router useRouter() const newsList ref([ { id: 1, title: Vue3 路由基础 }, { id: 2, title: Vue3 query 传参 }, { id: 3, title: Vue3 编程式导航 } ]) function goDetail(item) { router.push({ path: /newsDetail, query: { id: item.id, title: item.title } }) } /script style scoped li { margin-bottom: 12px; } span { display: inline-block; width: 180px; } a { margin-right: 10px; } /style1. 为什么要用v-forli v-foritem in newsList :keyitem.id这里使用v-for循环渲染新闻列表。newsList是一个数组里面有三条新闻数据。所以页面上会显示三条新闻每条新闻都带有标题和跳转方式。2.query传参怎么写router-link :to{ path: /newsDetail, query: { id: item.id, title: item.title } } 查看详情(query) /router-link这里的重点是path表示跳到哪个页面query表示带哪些参数过去如果点击第一条新闻地址可能变成/newsDetail?id1titleVue3路由基础这就是query传参。query的特点参数显示在地址栏问号后面使用灵活通过route.query接收3.params传参怎么写router-link :to{ name: detail2, params: { id: item.id, title: item.title } } 查看详情(params) /router-link这里用的是命名路由name: detail2。点击后地址可能变成/newsDetail2/1/Vue3路由基础这就是params传参。params的特点参数直接写在路径里更像 RESTful 风格通过route.params接收通常配合命名路由使用更稳4. 编程式导航router.push()function goDetail(item) { router.push({ path: /newsDetail, query: { id: item.id, title: item.title } }) }这里用到了const router useRouter()useRouter()的作用是获取路由器对象然后就可以在 JS 代码里手动跳转页面。这和router-link的区别是router-link写在模板中点链接跳转router.push()写在 JS 逻辑中执行函数跳转所以router.push()属于编程式导航。九、query 详情页如何接收 query 参数NewsDetail.vuetemplate div h2新闻详情页/h2 p新闻编号{{ route.query.id }}/p p新闻标题{{ route.query.title }}/p /div /template script setup import { useRoute } from vue-router const route useRoute() /script这里最关键的是const route useRoute()useRoute()用于获取当前路由对象。因为前面传的是query参数所以这里用route.query.id route.query.title来接收。所以一句话总结query 传参用route.query接收。十、params 详情页如何接收 params 参数NewsDetail2.vuetemplate div h2新闻详情页params传参/h2 p新闻编号{{ route.params.id }}/p p新闻标题{{ route.params.title }}/p /div /template script setup import { useRoute } from vue-router const route useRoute() /script这里和 query 详情页的区别就在于query 用route.queryparams 用route.params所以route.params.id route.params.title就是接收路径参数的方式。十一、用户中心嵌套路由详解用户中心组件UserView.vuetemplate div h2用户中心/h2 router-link to/user/message我的消息/router-link router-link to/user/profile我的资料/router-link hr / router-view / /div /template style scoped a { margin-right: 15px; text-decoration: none; color: black; } .router-link-active { color: red; font-weight: bold; } /style1. 为什么这里还要写一个router-view这正是嵌套路由的关键。在顶层App.vue里有一个router-view用于显示一级页面。而在UserView.vue里再写一个router-view就是为了显示它下面的子页面。你可以把它理解成App.vue 的 router-view → 显示 UserView.vue UserView.vue 的 router-view → 再显示 MessageView.vue 或 ProfileView.vue这就是嵌套路由的核心逻辑。2. 子页面组件MessageView.vuetemplate div h3我的消息/h3 p这里显示用户消息内容。/p /div /templateProfileView.vuetemplate div h3我的资料/h3 p这里显示用户个人资料。/p /div /template它们本身都很简单但通过嵌套路由能够出现在UserView.vue内部。十二、useRouter()和useRoute()的区别这两个特别容易混我这里单独总结一下。1.useRouter()作用获取路由器对象用来跳转页面例如const router useRouter() router.push(/news)2.useRoute()作用获取当前路由对象用来接收参数、读取路径信息例如const route useRoute() console.log(route.query.id) console.log(route.params.id)一句话记忆useRouter()跳useRoute()取这个记住了后面基本就不会混了。十三、query 和 params 的区别这个也是路由学习中的重点。1. query形式/newsDetail?id1titleVue3路由基础特点参数在问号后面灵活使用简单用route.query接收2. params形式/newsDetail2/1/Vue3路由基础特点参数直接写在路径中要和动态路由搭配用route.params接收一般配合命名路由使用3. 我的理解如果把它们比喻一下query更像“附带说明”params更像“路径本身的一部分”所以两者都很常用只是使用场景略有不同。十四、这个项目让我真正理解了什么通过这次自己从头到尾搭这个路由小项目我最大的收获不是会写几个 API而是开始真正理解 Vue3 路由的整体逻辑了。以前我觉得路由就是配路径点链接切页面但做完这个项目之后我发现路由其实串起来的是这样一条主线先在router/index.js中建立路径和组件的映射关系再在App.vue中放导航和路由出口通过router-link或router.push()进行跳转在新页面中通过useRoute()读取参数在更复杂的场景下通过children实现嵌套路由也就是说Vue Router 并不是一个孤立的工具而是整个 Vue 单页面应用的页面组织核心。十五、总结这个 Vue3 路由综合小案例把我目前学到的路由知识点基本都串起来了包括基础路由配置默认重定向router-linkrouter-viewquery 传参params 传参编程式导航嵌套路由通过这个项目我对 Vue3 路由的理解也更清楚了路由的本质是路径和组件的映射router-link负责跳转router-view负责显示useRouter()负责跳useRoute()负责取query和params都是常见传参方式children用于实现页面内部的子页面切换对于初学者来说我觉得这种“小项目驱动学习”的方式特别有效因为它不是死记硬背而是真正把知识点放到一个完整流程中去理解。如果后面继续完善这个项目还可以继续加入404 页面路由守卫keep-alive 缓存路由组件默认子路由命名视图这些都可以作为下一步的进阶内容。