当前位置: 首页 > 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.cnnetsun.cn/news/2054129.html

相关文章:

  • 别再傻傻分不清了!一文搞懂Visual Studio平台工具集(Platform Toolset)和MSBuild的关系
  • ViT凭什么能挑战CNN?深入拆解Vision Transformer的三大核心设计(Patch、Position、Class Token)与一个关键前提
  • 如何高效将OneNote笔记迁移到Markdown?这款开源工具帮你解决格式转换难题
  • 【TI毫米波雷达】IWR6843AOP驱动开发实战:从API调用到数据流解析
  • 高效批量下载利器:Kemono Downloader的完整指南
  • YOLO26全网最新创新点改进系列:引入BiFPN网络可学习的权重来学习不同输入特征的重要性,同时重复应用自上而下和自下而上的多尺度特征融合.,亲测显著涨点!
  • 边缘节点“失联率”超18%?Docker 27.1+Swarm Mode混合编排架构设计(附可验证拓扑图与心跳衰减公式)
  • MLOps中AI安全标准的技术实现与应用
  • Autosar Arxml实战:如何为你的CANFD报文设计动态Container布局(以Vector工具为例)
  • 从打印合同到软件发布:我是如何用UML活动图优化团队工作流的(实战复盘)
  • Win11下Yolov8开发环境避坑指南:从Anaconda配置到Pycharm工程验证
  • 从MySQL的B+树到ES的FST:一次索引数据结构选择的深度实战对比
  • 【ES】Elasticsearch运维实战:高频问题排查与优化手记
  • Windows 11 Mica 效果终极指南:让所有应用焕发毛玻璃质感
  • 还在为游戏操作别扭而烦恼?QKeyMapper让你一键解锁专业级按键映射
  • 从物理到逻辑:深入解析Underlay与Overlay网络的技术演进与融合之道
  • 韭菜盒子VSCode插件:程序员专属的实时投资信息中心终极指南
  • IG新功能“Reels可带商品链接”上线:申请条件+内容运营全攻略
  • 把扫雷游戏变成算法题:我是如何用C++向量(vector)和结构体模拟连锁爆炸的
  • Cursor Pro破解终极指南:解锁AI编程的无限可能
  • 别再硬算乘法器了!手把手教你用Matlab优化FIR内插滤波器,为FPGA省下90%资源
  • 别再只盯着运放了!用TI INA826这类仪表放大器搞定传感器信号调理,实测避坑指南
  • 从Java到前端:一名全栈开发者的成长之路
  • 告别霍尔传感器:用STM32的ADC实现BLDC无感控制(附反电动势过零检测代码)
  • Qt Creator新建QML项目踩坑记:为什么选了Qt 5.8就报‘No valid kits found’?
  • WinUtil终极指南:如何用开源工具重塑Windows系统体验
  • AWVS下载和安装保姆级教程
  • 告别串口调试助手:用Serial Studio+JSON配置文件,5分钟搭建你的嵌入式数据可视化看板
  • 毫米波雷达数据采集实战:手把手教你用DCA1000EVM捕获AWR1642的原始ADC数据
  • 【头部支付平台内部文档流出】:C++实现MCP网关的12项SLA保障策略(含P99<8ms实测报告)