Vue3 路由综合小案例实战:从基础跳转到 query、params 与嵌套路由
一、前言
最近在学习 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.js:
import { 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?id=1&title=Vue3路由基础路径本身还是/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.js:
import { createApp } from 'vue' import App from './App.vue' import router from './router' createApp(App).use(router).mount('#app')这里最关键的一句是:
.use(router)它的作用是:
把路由功能安装到 Vue 应用中。
如果不写这一句,项目中这些功能都不能正常使用:
<router-link><router-view>useRouter()useRoute()
所以一定要记住:
路由不是光写配置文件就行了,还必须在
main.js中注册。
七、App.vue:路由入口页面
项目中的App.vue如下:
<template> <div> <h1>Vue3 路由小案例</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; } </style>1.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-for="item in newsList" :key="item.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 @click="goDetail(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; } </style>1. 为什么要用v-for
<li v-for="item in newsList" :key="item.id">这里使用v-for循环渲染新闻列表。
newsList是一个数组,里面有三条新闻数据。
所以页面上会显示三条新闻,每条新闻都带有标题和跳转方式。
2.query传参怎么写
<router-link :to="{ path: '/newsDetail', query: { id: item.id, title: item.title } }" > 查看详情(query) </router-link>这里的重点是:
path表示跳到哪个页面query表示带哪些参数过去
如果点击第一条新闻,地址可能变成:
/newsDetail?id=1&title=Vue3路由基础这就是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.vue:
<template> <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.vue:
<template> <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.vue:
<template> <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; } </style>1. 为什么这里还要写一个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.vue
<template> <div> <h3>我的消息</h3> <p>这里显示用户消息内容。</p> </div> </template>ProfileView.vue
<template> <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?id=1&title=Vue3路由基础特点:
参数在问号后面
灵活
使用简单
用
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 缓存路由组件
默认子路由
命名视图
这些都可以作为下一步的进阶内容。
