当前位置: 首页 > news >正文

Vue3 路由综合小案例实战:从基础跳转到 query、params 与嵌套路由

一、前言

最近在学习 Vue3 的路由部分,为了把知识点真正串起来,我自己做了一个小项目。
这个项目虽然不大,但是把 Vue3 路由中很多核心内容都练到了,包括:

  • 基础路由切换

  • 默认重定向

  • router-linkrouter-view

  • query传参

  • 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 router

1.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.query

  • params 用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 路由的整体逻辑了。

以前我觉得路由就是:

  • 配路径

  • 点链接

  • 切页面

但做完这个项目之后,我发现路由其实串起来的是这样一条主线:

  1. 先在router/index.js中建立路径和组件的映射关系

  2. 再在App.vue中放导航和路由出口

  3. 通过router-linkrouter.push()进行跳转

  4. 在新页面中通过useRoute()读取参数

  5. 在更复杂的场景下,通过children实现嵌套路由

也就是说,Vue Router 并不是一个孤立的工具,而是整个 Vue 单页面应用的页面组织核心。


十五、总结

这个 Vue3 路由综合小案例,把我目前学到的路由知识点基本都串起来了,包括:

  • 基础路由配置

  • 默认重定向

  • router-link

  • router-view

  • query 传参

  • params 传参

  • 编程式导航

  • 嵌套路由

通过这个项目,我对 Vue3 路由的理解也更清楚了:

  • 路由的本质是路径和组件的映射

  • router-link负责跳转

  • router-view负责显示

  • useRouter()负责跳

  • useRoute()负责取

  • queryparams都是常见传参方式

  • children用于实现页面内部的子页面切换

对于初学者来说,我觉得这种“小项目驱动学习”的方式特别有效,因为它不是死记硬背,而是真正把知识点放到一个完整流程中去理解。

如果后面继续完善,这个项目还可以继续加入:

  • 404 页面

  • 路由守卫

  • keep-alive 缓存路由组件

  • 默认子路由

  • 命名视图

这些都可以作为下一步的进阶内容。

http://www.jsqmd.com/news/689748/

相关文章:

  • 从单机5万到集群320万QPS:某国家级IoT平台C++ MCP网关演进路径(含源码级协程调度器设计)
  • 宝塔面板用户必看:免费SSL证书自动续期与多域名管理的保姆级避坑指南
  • 5款翻译后格式不变的软件深度评测,留学生和外贸人狂喜!
  • ILA调试实战:从时钟约束到资源优化的核心要点
  • 2026 成人教育行业优质 GEO 优化服务商推荐榜 - GEO优化
  • 你的SPI Flash读写稳定吗?基于W25Q64的实战避坑指南(含超时处理与状态检查)
  • 从养兔子到写代码:趣谈斐波那契数列在面试与算法中的高频考点(附C/Python实现对比)
  • 【实战指南】从零到一:高效挖掘CNVD证书的完整路径
  • 量子测试工程师:2026职业新大陆
  • 告别重复配置!用VS2022项目模板一键搞定SDL2.26开发环境(附模板文件)
  • 从cap到hc22000:Hashcat 6.0+版本握手包破解的完整避坑指南(附最新格式转换工具)
  • FlicFlac深度重构:Windows音频格式转换的技术哲学与实现路径
  • 有线电视系统安装:从前端到终端的完整工程逻辑解析
  • 手把手复现DALL·E2核心思想:用PyTorch搭建简易版CLIP引导扩散模型(附代码)
  • 扩散模型分布式训练突破:Paris框架解析与实践
  • PyTorch多任务训练踩坑记:一个for循环里两次loss.backward()引发的RuntimeError
  • ANSYS Fluent实战:水平同心圆套管自然对流换热模拟与离散格式影响分析
  • 从‘套壳’到‘融合’:实战解析uni-app + Vue3项目中如何优雅地集成并控制第三方H5页面(含web-view深度使用指南)
  • 从图像处理到模型部署:聊聊PyTorch里squeeze和unsqueeze那些不起眼但关键的应用场景
  • 新手也能搞定!用Altium Designer为STM32F103C8T6最小系统板添加AHT20温湿度传感器(附完整PCB工程文件)
  • HTTrack网站镜像工具:技术架构与专业应用实践
  • D3KeyHelper:暗黑3效率革命,5分钟实现游戏操作自动化
  • 国内开发者福音:Gitee如何成为新手入门的首选代码管理平台
  • 从ChatDoctor到LLaVA-Med:盘点5个最值得关注的医疗大模型,以及它们到底能帮医生做什么?
  • 避坑指南:从零搭建TurtleBot3仿真环境时,我遇到的5个报错及解决方法(附完整代码)
  • 长文本处理技术:FlashAttention-2在Kaggle竞赛中的应用
  • 从附着到上网:深度解析LTE网络中PGW的IP地址分配与PDN连接建立
  • AI合规官必修课:GDPR 3.0实战
  • OpenLayers Feature 操作避坑指南:别再踩 `getSource()` 的坑了
  • 3分钟解决iPhone照片预览难题:Windows HEIC缩略图工具使用指南