Vue Router:从入门到实战
Vue Router 从入门到实战:一站式掌握Vue路由核心用法
在Vue开发中,单页应用(SPA)是主流的开发模式,而实现SPA页面之间的无缝切换,核心依赖就是Vue官方的路由管理器------Vue Router。它能帮我们建立路径与页面的映射关系,实现无刷新的页面跳转,是Vue生态中不可或缺的核心插件。本文将从路由基础概念出发,一步步讲解Vue Router的基本使用、导航传参、高级配置以及嵌套路由、路由守卫等实战技巧,帮助你快速上手并灵活运用Vue Router。
一、先搞懂:路由与单页应用的核心概念
在使用Vue Router之前,我们需要先理清几个基础概念,这是理解路由工作原理的关键。
1.1 什么是路由?
路由的本质是一种映射关系:
-
生活中的路由:路由器实现IP与设备的映射;
-
Vue中的路由:URL路径与页面组件的映射关系,通过路径变化匹配对应的组件,实现页面切换。
1.2 Vue Router 是什么?
Vue Router是Vue.js官方提供的路由插件,是一个第三方模块包,为Vue应用提供了富有表现力、可配置的路由能力,核心特性包括:动态路由定义、精细的导航控制、基于组件的路由配置、支持多种历史模式、滚动控制、自动编码等。
1.3 单页应用(SPA)与多页应用(MPA)
Vue Router主要服务于单页应用,我们可以通过一张表清晰区分SPA和MPA:
| 特性 | 单页面应用(SPA) | 多页面应用(MPA) |
|---|---|---|
| 实现方式 | 一个HTML页面 | 多个HTML页面 |
| 页面更新 | 按需更新 | 整体更新 |
| 页面性能 | 高 | 中等 |
| 开发效率 | 好 | 一般 |
| 用户体验 | 优秀(无刷新) | 一般(有刷新) |
| 首屏加载 | 较慢 | 较快 |
| SEO | 较差 | 优秀 |
| SPA核心优势 :体验流畅、开发效率高,也是Vue开发的主流选择;缺点:首屏加载慢、不利于SEO,可通过服务端渲染(SSR)等方式优化。 |
1.4 Vue组件的分类与规范
在路由开发中,为了便于管理,我们会将Vue组件分为两类,二者本质无区别,仅为逻辑划分:
-
页面组件 :独立展示、配合路由切换,不可复用,存放在
src/views目录下; -
复用组件 :用于组装页面组件,可多次复用,存放在
src/components目录下。
二、Vue Router 基本使用:4+2核心步骤
Vue Router的基础使用遵循4个固定步骤 +2个核心步骤 ,简称4+2,按步骤操作即可快速实现基础路由功能。本文基于Vue3 + Vite环境讲解,Vue3中Vue Router的使用为组合式API风格,与Vue2有一定区别。
2.1 四个固定步骤:下载→导入→创建→注册
这四步是搭建路由的基础,完成后路由将接管应用的路径管理。
-
下载Vue Router模块:使用yarn或npm安装
Bashyarn add vue-router # 或 npm install vue-router -
导入相关函数:从vue-router中导入创建路由和历史模式的函数
JavaScriptimport { createRouter, createWebHashHistory } from 'vue-router' -
创建路由实例:配置历史模式和路由表(路径与组件的映射)
JavaScriptconst router = createRouter({ // 哈希模式,路径带#,开发中默认使用 history: createWebHashHistory(), // 路由表:配置path与component的对应关系 routes: [] }) -
注册路由实例:将路由挂载到Vue应用中,让路由规则生效
JavaScriptimport { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.use(router) // 注册路由 app.mount('#app')
完成以上四步后,浏览器地址栏会出现/#/,表示路由已成功接管应用。
2.2 两个核心步骤:配置路由表→添加路由出口
这两步是实现路径与组件联动的关键,让路径变化能渲染对应的组件。
-
配置路由表 :在
routes数组中添加路径与页面组件的映射,先在src/views创建页面组件(如Find.vue、My.vue),再配置:JavaScript// 导入页面组件 import Find from '@/views/Find.vue' import My from '@/views/My.vue' import Friend from '@/views/Friend.vue' const router = createRouter({ history: createWebHashHistory(), routes: [ { path: '/find', component: Find }, { path: '/my', component: My }, { path: '/friend', component: Friend } ] })注意:
@是Vue脚手架的别名,代指src目录,可快速引入组件。 -
添加路由出口 :在App.vue中添加
<router-view />,这是路径匹配的组件渲染的位置,也是路由的核心占位符:Plain<template> <!-- 路由出口:匹配的组件将在这里渲染 --> <router-view /> </template>
2.3 路由运作原理
当浏览器URL路径发生改变时,Vue Router会匹配路由表routes中的path值,若命中则将对应的component渲染到<router-view />的位置;若未命中,则页面显示空白。
2.4 路由模块抽离封装
上述代码若全部写在main.js中,会导致代码臃肿,最佳实践是将路由模块抽离到单独的文件中,便于管理和维护。
-
新建
src/router/index.js,将路由创建、配置的代码移至该文件,并导出路由实例:JavaScript// src/router/index.js import { createRouter, createWebHashHistory } from 'vue-router' import Find from '@/views/Find.vue' import My from '@/views/My.vue' import Friend from '@/views/Friend.vue' const router = createRouter({ history: createWebHashHistory(), routes: [ { path: '/find', component: Find }, { path: '/my', component: My }, { path: '/friend', component: Friend } ] }) export default router -
在
main.js中导入并注册:JavaScript// src/main.js import { createApp } from 'vue' import App from './App.vue' import router from './router' // 导入路由实例 const app = createApp(App) app.use(router) app.mount('#app')
三、声明式导航:点击跳转的优雅实现
手动输入地址切换页面显然不友好,Vue Router提供了声明式导航 组件<router-link>,替代原生<a>标签实现点击跳转,无需担心刷新页面,且自带高亮类名,开发更高效。
3.1 基本使用
<router-link>的核心属性是to,用于指定跳转的路径,本质还是<a>标签,但做了无刷新处理:
Plain
<template>
<nav>
<router-link to="/find">发现音乐</router-link>
<router-link to="/my">我的音乐</router-link>
<router-link to="/friend">朋友</router-link>
</nav>
<router-view />
</template>
3.2 自带高亮类名
点击<router-link>后,当前激活的链接会自动添加两个高亮类名,无需手动操作,直接为类名写样式即可实现导航高亮:
-
router-link-active:模糊匹配 ,只要路径以目标路径开头,就会匹配(如/find/123会匹配to="/find"); -
router-link-exact-active:精确匹配 ,只有路径与目标路径完全一致时才会匹配(如仅/find匹配to="/find")。
高亮样式示例:
CSS
<style>
nav a.router-link-active {
background: red;
color: #fff;
padding: 4px 8px;
border-radius: 4px;
}
</style>
3.3 声明式导航传参
开发中常需要跳转时传递参数(如跳转到详情页携带ID),Vue Router提供了查询参数传参 和动态路由传参两种方式,满足不同业务场景。
方式1:查询参数传参(适合多参数)
类似URL的?key=value形式,无需修改路由表,直接在to中拼接参数,适合传递多个参数。
-
传参:支持字符串和对象两种写法
Plain<!-- 字符串写法 --> <router-link to="/friend?id=10086&name=张三">朋友</router-link> <!-- 对象写法(推荐,适合动态参数) --> <router-link :to="{ path: '/friend', query: { id: 10086, name: '张三' } }">朋友</router-link> -
接参 :使用
useRoute获取当前路由对象,通过route.query获取参数Plain<script setup> import { useRoute } from 'vue-router' const route = useRoute() console.log(route.query.id) // 10086 console.log(route.query.name) // 张三 </script>
方式2:动态路由传参(适合单参数,更优雅)
先在路由表中占位参数 ,再在跳转时传入具体值,路径更简洁(如/friend/10086),适合传递单个核心参数(如ID)。
-
配置动态路由表 :在
path中通过/:参数名占位,可给路由命名(方便对象写法跳转)JavaScript// src/router/index.js const router = createRouter({ routes: [ { name: 'Friend', // 路由命名 path: '/friend/:fid', // 动态参数占位:fid为参数名 component: Friend } ] }) -
传参:支持字符串和对象两种写法
Plain<!-- 字符串写法 --> <router-link to="/friend/10086">朋友</router-link> <!-- 对象写法(推荐,需配合路由name) --> <router-link :to="{ name: 'Friend', params: { fid: 10086 } }">朋友</router-link>注意:对象写法传动态参数时,不能用path,必须用路由name。
-
接参 :使用
useRoute,通过route.params获取参数Plain<script setup> import { useRoute } from 'vue-router' const route = useRoute() console.log(route.params.fid) // 10086 </script>
两种传参方式对比
| 特性 | 查询参数传参 | 动态路由传参 |
|---|---|---|
| 路由表配置 | 无需修改 | 需通过/:参数名占位 |
| 路径形式 | /path?k=v&k2=v2 | /path/value |
| 适用场景 | 传递多个参数 | 传递单个核心参数 |
| 获取方式 | route.query.参数名 | route.params.参数名 |
四、Vue Router 高级配置:让路由更实用
掌握基础使用后,通过一些高级配置可以解决开发中的常见问题(如页面空白、404、路径带#等),让路由功能更完善。
4.1 重定向:解决默认路径空白问题
网页打开时,默认路径是/,若路由表中未配置该路径,页面会显示空白,重定向 可实现匹配/时,强制跳转到指定路径(如/find)。
语法 :{ path: 匹配路径, redirect: 重定向路径 }
JavaScript
const router = createRouter({
routes: [
// 访问/,自动跳转到/find
{ path: '/', redirect: '/find' },
{ path: '/find', component: Find },
{ path: '/my', component: My }
]
})
4.2 404页面:处理无效路径
当用户输入的路径在路由表中无匹配时,可配置404页面,给用户友好的提示,而非空白页面。
配置要点:
-
先在
src/views创建404.vue页面组件; -
路由表中配置
path: "*"(匹配任意路径),必须放在路由表最后(路由匹配是按顺序的,避免覆盖正常路由)。
代码示例:
Plain
<!-- src/views/404.vue -->
<template>
<div style="text-align: center; margin-top: 50px;">
<h3>404</h3>
<p>你访问的页面去了月球~</p>
<!-- 跳回首页 -->
<router-link to="/">返回首页</router-link>
</div>
</template>
JavaScript
// src/router/index.js
import _404 from '@/views/404.vue'
const router = createRouter({
routes: [
{ path: '/', redirect: '/find' },
{ path: '/find', component: Find },
{ path: '/my', component: My },
{ path: '/friend/:fid', component: Friend },
// 404配置,放在最后
{ path: '*', component: _404 }
]
})
4.3 路由模式:去掉路径中的#
Vue Router默认使用哈希模式(hash) ,路径带#(如http://localhost:5173/#/find),若想让路径更美观,可切换为历史模式(history) ,路径无#(如http://localhost:5173/find)。
语法 :将createWebHashHistory替换为createWebHistory
JavaScript
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
// 历史模式,路径无#
history: createWebHistory(),
routes: []
})
注意 :历史模式在开发环境中可正常使用(Vite已做兼容),但上线部署时需要服务器端支持(如Nginx配置),否则刷新页面会出现404,而哈希模式无需服务器配置,兼容性更好。
五、编程式导航:JS代码实现路由跳转
声明式导航适合点击跳转 的场景,而开发中常需要通过JS代码主动触发跳转 (如登录成功后跳转到首页、定时器延迟跳转),这时候就需要编程式导航。
5.1 基本使用
编程式导航的核心是useRouter获取路由实例,通过router.push()实现跳转,支持字符串路径 和对象配置 两种写法,与<router-link>的to属性写法一致。
Plain
<script setup>
import { useRouter } from 'vue-router'
import { onMounted } from 'vue'
// 获取路由实例
const router = useRouter()
// 组件挂载后,延迟2秒跳转到朋友页
onMounted(() => {
setTimeout(() => {
// 字符串写法
router.push('/friend')
// 对象写法-通过path
router.push({ path: '/friend' })
// 对象写法-通过路由name(推荐)
router.push({ name: 'Friend' })
}, 2000)
})
</script>
5.2 编程式导航传参
与声明式导航传参完全一致 ,同样支持查询参数和动态路由参数,写法仅将<router-link>的to属性内容放入router.push()中。
方式1:查询参数传参
JavaScript
// 字符串写法
router.push('/friend?id=110&name=李四')
// 对象写法
router.push({ path: '/friend', query: { id: 110, name: '李四' } })
// 接参还是用route.query
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.id)
方式2:动态路由传参
JavaScript
// 字符串写法
router.push('/friend/110')
// 对象写法(配合路由name)
router.push({ name: 'Friend', params: { fid: 110 } })
// 接参还是用route.params
console.log(route.params.fid)
六、嵌套路由与路由守卫:应对复杂业务场景
实际开发中,页面结构往往更复杂(如一个页面中包含多个子页面切换),且需要做路由权限控制(如未登录不能访问个人中心),这时候就需要嵌套路由和路由守卫来解决。
6.1 嵌套路由:实现页面内的子路由切换
嵌套路由指在一个路由页面中,再配置一套子路由,实现页面内的无刷新切换(如网易云音乐的"发现音乐"页中,包含"推荐"、"排行榜"、"歌单"子页面)。
实现步骤(3步)
-
创建子页面组件 :在
src/views创建子组件(如Recommend.vue、Ranking.vue、SongList.vue); -
配置嵌套路由表 :在父路由的
routes配置中,添加children数组,配置子路由规则,子路由的path推荐不加/; -
添加子路由出口和导航 :在父页面组件中,添加
<router-view />(子组件渲染位置)和<router-link>(子导航)。
代码示例
第一步:配置嵌套路由表
JavaScript
// src/router/index.js
import Recommend from '@/views/Recommend.vue'
import Ranking from '@/views/Ranking.vue'
import SongList from '@/views/SongList.vue'
const router = createRouter({
history: createWebHashHistory(),
routes: [
{
path: '/find',
component: Find,
redirect: '/find/recommend', // 重定向,防止子路由默认空白
// 嵌套子路由
children: [
{ path: 'recommend', component: Recommend }, // 子路由path不加/
{ path: 'ranking', component: Ranking },
{ path: 'songlist', component: SongList }
]
}
]
})
第二步:父页面添加子导航和出口
Plain
<!-- src/views/Find.vue -->
<template>
<div class="find">
<h3>发现音乐</h3>
<!-- 子路由导航 -->
<nav>
<router-link to="/find/recommend">推荐</router-link>
<router-link to="/find/ranking">排行榜</router-link>
<router-link to="/find/songlist">歌单</router-link>
</nav>
<!-- 子路由出口:子组件在这里渲染 -->
<router-view />
</div>
</template>
嵌套路由注意点
-
子路由的
path推荐不加/,若加/则表示根路径,会导致匹配异常; -
子路由跳转时,
to需要写完整路径 (父路径+子路径,如/find/recommend); -
为了防止子路由默认空白,需给父路由添加重定向到默认子路由。
6.2 路由守卫:实现路由权限控制
路由守卫(导航守卫)是Vue Router提供的路由拦截机制 ,可在路由跳转前/后执行回调函数,实现权限校验、页面埋点、路由跳转控制 等功能,最常用的是全局前置守卫 router.beforeEach。
全局前置守卫基本使用
router.beforeEach会在每个路由跳转前触发 ,接收一个回调函数,参数为to(即将进入的路由)和from(即将离开的路由),通过返回值控制路由是否跳转。
语法:
JavaScript
router.beforeEach((to, from) => {
// to:即将进入的路由对象(包含path、name、params等)
// from:即将离开的路由对象
// 返回值控制导航:
// 1. return false:取消导航,不跳转
// 2. return true/undefined:正常放行,跳转到目标路由
// 3. return '路径':重定向到指定路径
})
实战:未登录禁止访问个人中心
模拟登录状态,实现未登录时,点击"我的音乐"跳转会提示并取消导航,登录后正常放行。
JavaScript
// src/router/index.js
// 模拟登录状态:true为已登录,false为未登录
const isLogin = false
router.beforeEach((to, from) => {
// 判断:未登录 且 要跳转到/my路径
if (!isLogin && to.path === '/my') {
alert('请先登录后再访问!')
return false // 取消导航
}
// 其他情况正常放行
return true
})
七、总结
Vue Router是Vue开发的核心插件,掌握它是实现单页应用的基础,本文核心知识点可总结为以下几点:
-
路由的本质是路径与组件的映射关系,Vue Router是Vue官方的路由管理器;
-
基础使用遵循4+2步骤,且建议将路由模块抽离封装,便于维护;
-
导航分为声明式()和编程式(router.push),二者传参方式一致,支持查询参数和动态路由参数;
-
高级配置包含重定向、404页面、路由模式,解决开发中的常见问题;
-
嵌套路由通过
children配置,实现页面内的子路由切换,需注意子路由路径和完整跳转路径; -
路由守卫通过
router.beforeEach实现路由权限控制,是开发中实现登录拦截的核心方式。
掌握以上内容,就能应对大部分Vue开发中的路由场景,后续可结合Vue Router的官方文档,探索更多高级特性(如路由独享守卫、组件内守卫、滚动行为等),让路由使用更灵活、高效。