1. 基本概念
Vue Router 是 Vue.js 的官方路由管理器。主要功能包括:
-
路由模式:Hash 模式和 History 模式
-
动态路由匹配
-
嵌套路由
-
导航守卫
-
路由元信息
-
路由懒加载
2. 基础配置和使用
// router/index.ts
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'Home',
component: () => import('@/views/Home.vue'),
meta: {
title: '首页',
requiresAuth: true
}
},
{
path: '/about/:id', // 动态路由
name: 'About',
component: () => import('@/views/About.vue'),
// 嵌套路由
children: [
{
path: 'profile',
component: () => import('@/views/Profile.vue')
}
]
},
{
path: '/:pathMatch(.*)*', // 404 路由
name: 'NotFound',
component: () => import('@/views/NotFound.vue')
}
]
const router = createRouter({
history: createWebHistory(), // 使用 history 模式
routes
})
export default router
3. 导航守卫
// 全局前置守卫
router.beforeEach((to, from, next) => {
// 检查路由是否需要认证
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login')
} else {
next()
}
})
// 全局后置守卫
router.afterEach((to, from) => {
// 更新页面标题
document.title = to.meta.title || 'Default Title'
})
// 路由独享守卫
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
if (isAdmin()) {
next()
} else {
next('/403')
}
}
}
// 组件内守卫
export default {
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被验证前调用
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
},
beforeRouteLeave(to, from, next) {
// 导航离开该组件的对应路由时调用
}
}
4. 路由跳转方法
<template>
<!-- 声明式导航 -->
<router-link to="/home">首页</router-link>
<router-link :to="{ name: 'About', params: { id: 123 }}">关于</router-link>
<!-- 编程式导航 -->
<button @click="handleNavigate">跳转</button>
</template>
<script setup lang="ts">
import { useRouter, useRoute } from 'vue-router'
const router = useRouter()
const route = useRoute()
const handleNavigate = () => {
// 字符串路径
router.push('/home')
// 对象
router.push({
name: 'About',
params: { id: 123 },
query: { search: 'keyword' }
})
// 带 replace 的导航
router.replace('/home')
// 前进/后退
router.go(-1) // 后退
router.go(1) // 前进
}
// 获取当前路由信息
console.log(route.params.id)
console.log(route.query.search)
</script>
5. 路由懒加载
// 基础懒加载
const routes = [
{
path: '/home',
component: () => import('@/views/Home.vue')
}
]
// 分组懒加载
const routes = [
{
path: '/admin',
component: () => import(/* webpackChunkName: "admin" */ '@/views/Admin.vue')
}
]
6. 路由模式对比
// Hash 模式 (#)
const router = createRouter({
history: createWebHashHistory(),
routes
})
// History 模式 (需要服务器配置)
const router = createRouter({
history: createWebHistory(),
routes
})
7. 实际应用示例
// 权限路由示例
const router = createRouter({
history: createWebHistory(),
routes: [
{
path: '/login',
component: () => import('@/views/Login.vue')
},
{
path: '/',
component: () => import('@/layouts/MainLayout.vue'),
children: [
{
path: 'dashboard',
component: () => import('@/views/Dashboard.vue'),
meta: {
requiresAuth: true,
roles: ['admin', 'user']
}
}
]
}
]
})
// 权限守卫
router.beforeEach(async (to, from, next) => {
const store = useStore()
if (to.meta.requiresAuth) {
if (!store.isLoggedIn) {
next('/login')
} else if (to.meta.roles && !to.meta.roles.includes(store.userRole)) {
next('/403')
} else {
next()
}
} else {
next()
}
})
要点:
- 路由模式区别:
-
Hash 模式:使用 URL hash 变化触发路由,兼容性好
-
History 模式:需要服务器配置,但 URL 更美观
- 导航守卫执行顺序:
-
导航被触发
-
在失活的组件里调用 beforeRouteLeave
-
调用全局 beforeEach 守卫
-
在重用的组件里调用 beforeRouteUpdate
-
在路由配置里调用 beforeEnter
-
解析异步路由组件
-
在被激活的组件里调用 beforeRouteEnter
-
调用全局 beforeResolve 守卫
-
导航确认
-
调用全局 afterEach 钩子
-
DOM 更新
-
调用 beforeRouteEnter 守卫中传给 next 的回调函数
- 性能优化:
-
路由懒加载
-
路由组件缓存 (keep-alive)
-
预加载关键路由
- 安全考虑:
-
权限控制
-
路由参数验证
-
防止重复点击