路由是现代前端单页应用(SPA)的核心能力之一,它让我们无需刷新页面就能实现不同视图的切换。Vue Router 作为 Vue 官方的路由管理器,与 Vue.js 深度集成,是构建 Vue 应用的必备工具。本文将从基础到进阶,全面讲解 Vue Router 的核心知识点,帮助你彻底掌握 Vue 路由的使用。
一、Vue Router 基础入门
1. 什么是 Vue Router
Vue Router 是 Vue.js 官方的路由插件,它的核心作用是:
- 建立 URL 路径与组件之间的映射关系
- 实现组件的按需加载和页面切换
- 管理路由的历史记录,模拟浏览器的前进 / 后退功能
2. 安装与基本配置
安装(以 Vue3 + Vue Router4 为例)
# npm
npm install vue-router@4
# yarn
yarn add vue-router@4
# pnpm
pnpm add vue-router@4
基本配置步骤
- 创建路由文件(src/router/index.js):
javascript
// 1. 导入必要的依赖
import { createRouter, createWebHistory } from 'vue-router'
// 导入需要路由的组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'
// 2. 定义路由规则
const routes = [
{
path: '/', // URL路径
name: 'Home', // 路由名称(可选)
component: Home // 对应组件
},
{
path: '/about',
name: 'About',
component: About
}
]
// 3. 创建路由实例
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL), // 路由模式(HTML5 History模式)
routes // 路由规则
})
// 4. 导出路由实例
export default router
- 在 main.js 中注册路由:
javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(router) // 注册路由插件
app.mount('#app')
- 在 App.vue 中添加路由出口:
javascript
<template>
<div id="app">
<!-- 路由链接:相当于a标签,不会刷新页面 -->
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<!-- 路由出口:匹配的组件将渲染在这里 -->
<router-view></router-view>
</div>
</template>
3. 核心概念解析
- router-link :Vue Router 提供的导航组件,替代原生
<a>标签,点击时不会触发页面刷新,只会更新 URL 和<router-view>内容 - router-view:路由出口,所有匹配当前 URL 的组件都会渲染到这个位置
- 路由模式 :
createWebHistory():HTML5 History 模式(推荐),URL 无#,需要后端配置支持createWebHashHistory():Hash 模式,URL 带#,无需后端配置
二、路由进阶用法
1. 动态路由匹配
用于匹配动态变化的路径(如:用户详情页/user/123):
javascript
// 路由规则
{
path: '/user/:id', // :id为动态参数
name: 'User',
component: () => import('../views/User.vue') // 懒加载组件
}
在组件中获取动态参数:
javascript
<template>
<div>用户ID:{{ $route.params.id }}</div>
</template>
<script setup>
// 方式1:使用$route(不推荐,耦合度高)
// 方式2:使用useRoute组合式API(推荐)
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.params.id) // 获取动态参数id
</script>
2. 嵌套路由
用于实现页面的层级嵌套(如:后台管理系统的侧边栏 + 内容区):
javascript
// 路由规则
{
path: '/dashboard',
component: () => import('../views/Dashboard.vue'),
// 嵌套路由规则
children: [
{
path: '', // 默认子路由
component: () => import('../views/Dashboard/Home.vue')
},
{
path: 'profile', // 等价于 /dashboard/profile
component: () => import('../views/Dashboard/Profile.vue')
},
{
path: 'settings', // 等价于 /dashboard/settings
component: () => import('../views/Dashboard/Settings.vue')
}
]
}
在父组件中添加子路由出口:
javascript
<!-- Dashboard.vue -->
<template>
<div class="dashboard">
<aside>
<router-link to="/dashboard">首页</router-link>
<router-link to="/dashboard/profile">个人信息</router-link>
<router-link to="/dashboard/settings">设置</router-link>
</aside>
<main>
<!-- 子路由出口 -->
<router-view></router-view>
</main>
</div>
</template>
3. 编程式导航
除了使用<router-link>,还可以通过代码实现路由跳转:
javascript
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
// 跳转方式1:通过路径
const goToAbout = () => {
router.push('/about')
}
// 跳转方式2:通过路由名称(推荐,解耦)
const goToUser = () => {
router.push({
name: 'User',
params: { id: 123 }
})
}
// 跳转方式3:带查询参数
const goToSearch = () => {
router.push({
path: '/search',
query: { keyword: 'vue' } // URL:/search?keyword=vue
})
}
// 替换当前路由(不会新增历史记录)
const replaceRoute = () => {
router.replace('/about')
}
// 前进/后退
const goBack = () => {
router.go(-1) // 后退一步
}
const goForward = () => {
router.go(1) // 前进一步
}
</script>
4. 路由守卫
路由守卫用于控制路由的访问权限(如:登录验证、权限校验),分为三类:
(1)全局守卫
javascript
// src/router/index.js
// 全局前置守卫:路由跳转前触发
router.beforeEach((to, from, next) => {
// to:目标路由对象
// from:当前路由对象
// next:放行函数(Vue3中已废弃,直接返回true/false或路由对象)
// 示例:登录验证
const isLogin = localStorage.getItem('token')
// 未登录且访问的不是登录页,跳转到登录页
if (!isLogin && to.path !== '/login') {
return '/login'
}
// 已登录且访问登录页,跳转到首页
if (isLogin && to.path === '/login') {
return '/'
}
// 放行
return true
})
// 全局后置守卫:路由跳转后触发(无拦截能力)
router.afterEach((to, from) => {
// 示例:修改页面标题
document.title = to.meta.title || 'Vue App'
})
(2)路由独享守卫
javascript
{
path: '/admin',
component: () => import('../views/Admin.vue'),
// 路由独享守卫
beforeEnter: (to, from) => {
// 示例:权限校验
const role = localStorage.getItem('role')
if (role !== 'admin') {
alert('无管理员权限!')
return false
}
return true
},
meta: { requiresAuth: true } // 自定义元信息
}
(3)组件内守卫
javascript
<script setup>
import { onBeforeRouteEnter, onBeforeRouteUpdate, onBeforeRouteLeave } from 'vue-router'
// 进入组件前触发(此时组件实例未创建,无法访问this)
onBeforeRouteEnter((to, from) => {
// 可以通过next传递数据
return (vm) => {
// vm是组件实例
console.log('进入组件', vm)
}
})
// 路由参数更新时触发(如:/user/123 → /user/456)
onBeforeRouteUpdate((to, from) => {
console.log('路由参数更新', to.params.id)
})
// 离开组件前触发(可用于确认是否离开)
onBeforeRouteLeave((to, from) => {
const confirmLeave = confirm('确定要离开吗?')
if (!confirmLeave) {
return false // 阻止离开
}
return true
})
</script>
5. 路由懒加载
为了优化应用加载性能,我们可以将路由组件按需加载(懒加载):
javascript
// 方式1:基本懒加载
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
// 方式2:懒加载并分组(打包时合并到同一个chunk)
const Home = () => import(/* webpackChunkName: "home" */ '../views/Home.vue')
const About = () => import(/* webpackChunkName: "about" */ '../views/About.vue')
{
path: '/home',
component: Home
},
{
path: '/about',
component: About
}
三、常见问题与解决方案
1. 刷新页面 404(History 模式)
原因 :History 模式下,刷新页面时浏览器会直接请求后端该路径,后端无对应资源则返回 404。解决方案:
-
Nginx 配置: nginx
location / { try_files $uri $uri/ /index.html; } -
Apache 配置: apache
FallbackResource /index.html
2. 路由参数更新但组件不刷新
原因 :相同路由的参数变化时,组件会被复用,不会重新渲染。解决方案:
javascript
<script setup>
import { useRoute, watch } from 'vue-router'
const route = useRoute()
// 监听路由参数变化
watch(() => route.params.id, (newId, oldId) => {
// 重新加载数据
console.log('ID变化:', newId)
})
</script>
3. 路由重复跳转报错
原因 :重复点击相同路由链接时,Vue Router 会抛出错误。解决方案:
javascript
// src/router/index.js
// 重写push方法
const originalPush = router.push
router.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
四、Vue2 vs Vue3 路由差异
表格
| 特性 | Vue2 (Vue Router3) | Vue3 (Vue Router4) |
|---|---|---|
| 创建路由 | new VueRouter() | createRouter() |
| 路由模式 | mode: 'history' | history: createWebHistory() |
| 组合式 API | 无 | useRouter() / useRoute() |
| 守卫 next 方法 | 必须调用 next () | 直接返回值(true/false/ 路由对象) |
| 生命周期 | beforeRouteEnter 需用 next (vm) | 支持 setup 语法糖,onBeforeRouteEnter |
总结
- 核心基础 :Vue Router 的核心是建立路径与组件的映射,通过
<router-link>导航、<router-view>渲染,核心模式有 History 和 Hash 两种。 - 进阶能力:动态路由实现参数化匹配,嵌套路由实现层级布局,编程式导航支持代码控制跳转,路由守卫实现权限控制。
- 性能优化:路由懒加载能有效减小首屏体积,解决 History 模式刷新 404 需配置后端重定向。
掌握以上知识点,你就能应对绝大多数 Vue 项目中的路由场景。建议结合实际项目多练习,尤其是路由守卫和动态路由的使用,这是面试和实际开发中的高频考点。