一、前言:为什么需要 Vue Router?
在传统多页面应用中,页面跳转依赖后端路由(通过 URL 请求不同 HTML 文件),存在页面刷新、加载缓慢、用户体验差等问题。而 Vue 作为单页面应用(SPA)框架,需要一套前端路由方案来实现 “无刷新页面切换”——Vue Router 应运而生。
Vue Router 是 Vue 官方配套的路由插件,核心作用是:
- 建立 URL 与组件的映射关系
- 实现无刷新的页面跳转(通过操作 History API 或 Hash)
- 支持路由参数、嵌套路由、路由守卫等高级功能
- 与 Vue 生态深度集成,实现组件化的路由管理
本文将从安装配置→核心用法→进阶技巧→实战案例,带你全面掌握 Vue Router(基于 Vue 3 + Vue Router 4,兼容 Vue 2 迁移指南)。
二、快速上手:Vue Router 安装与基础配置
1. 安装依赖
根据项目环境选择安装方式:
# Vue 3 + Vue Router 4(推荐) npm install vue-router@4 # 或 yarn yarn add vue-router@4 # Vue 2 + Vue Router 3(兼容旧项目) npm install vue-router@3 |
2. 基础配置步骤(Vue 3 示例)
步骤 1:创建路由实例
在src/router/index.js中配置路由规则:
// 1. 导入依赖 import { createRouter, createWebHistory } from 'vue-router' // 导入需要路由的组件 import Home from '@/views/Home.vue' import About from '@/views/About.vue' import NotFound from '@/views/NotFound.vue' // 2. 定义路由规则(path→component映射) const routes = [ { path: '/', // 根路径 name: 'Home', // 路由名称(可选,用于编程式导航) component: Home // 对应组件 }, { path: '/about', name: 'About', component: About }, { path: '/:pathMatch(.*)*', // 404路由(匹配所有未定义路径) name: 'NotFound', component: NotFound } ] // 3. 创建路由实例 const router = createRouter({ history: createWebHistory(import.meta.env.BASE_URL), // HTML5 History模式(无#) // history: createWebHashHistory(), // Hash模式(URL带#,兼容性更好) routes // 注入路由规则 }) // 4. 导出路由实例 export default router |
步骤 2:在 Vue 中注入路由
在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') |
步骤 3:使用路由导航与视图
在App.vue中添加路由链接和路由出口:
"> 链接(替代a标签,无刷新跳转) --> 首页 about">关于我们-link> > 出口:匹配的组件将渲染在这里 --> <router-view /> </div> 激活的路由链接样式(默认类名:router-link-active) */ .router-link-active { color: red; font-weight: bold; } </style> |
三、核心用法:掌握路由的关键特性
1. 路由参数(动态路由)
场景:需要根据 URL 参数渲染不同内容(如详情页)。
配置动态路由:
// router/index.js const routes = [ { path: '/user/:id', // :id为动态参数(可多个:/user/:id/:name) name: 'User', component: () => import('@/views/User.vue') // 懒加载组件(优化性能) } ] |
在组件中获取参数:
<!-- User.vue --> <template> >用户ID:{{ $route.params.id }} </template> setup> // 方式1:通过$route(简易) import { useRoute } from 'vue-router' const route = useRoute() console.log(route.params.id) // 打印URL中的id参数 // 方式2:解构参数(推荐,更清晰) const { id } = route.params > |
2. 编程式导航(替代 router-link)
场景:需要通过按钮点击等逻辑触发跳转。
// 组件中使用 import { useRouter } from 'vue-router' const router = useRouter() // 1. 跳转到指定路径 const goToHome = () => { router.push('/') } // 2. 通过路由名称跳转(需配置name) const goToAbout = () => { router.push({ name: 'About' }) } // 3. 带参数跳转 const goToUser = (userId) => { router.push({ name: 'User', params: { id: userId } // 动态参数 }) // 或 query参数(URL拼接:/user?id=123) // router.push({ path: '/user', query: { id: userId } }) } // 4. 后退/前进 const goBack = () => { router.go(-1) // 后退1步 // router.forward() // 前进一步 } |
3. 嵌套路由(多级路由)
场景:页面存在多级导航(如首页→商品列表→商品详情)。
配置嵌套路由:
// router/index.js const routes = [ { path: '/product', name: 'Product', component: () => import('@/views/Product.vue'), children: [ // 子路由 { path: 'list', // 子路径(URL:/product/list) name: 'ProductList', component: () => import('@/views/ProductList.vue') }, { path: 'detail/:id', // 子路由带参数(URL:/product/detail/1) name: 'ProductDetail', component: () => import('@/views/ProductDetail.vue') } ] } ] |
父组件中添加子路由出口:
<template> <div> 2>商品模块2> -link to="/product/list">商品列表 在这里 --> > |
4. 路由守卫(权限控制核心)
路由守卫用于拦截路由跳转,实现权限校验、页面拦截等功能,分为 3 类:
(1)全局守卫(影响所有路由)
// router/index.js // 路由跳转前触发(可拦截) router.beforeEach((to, from, next) => { // to:即将进入的路由 // from:即将离开的路由 // next:放行函数(next()放行,next('/login')跳转,next(false)取消) // 示例:未登录拦截(除了登录页都需要登录) const isLogin = localStorage.getItem('token') if (to.path !== '/login' && !isLogin) { next('/login') // 未登录跳转到登录页 } else { next() // 已登录放行 } }) // 路由跳转后触发(不可拦截) router.afterEach((to, from) => { // 示例:修改页面标题 document.title = to.meta.title || 'Vue Router示例' }) |
(2)路由独享守卫(只影响当前路由)
// router/index.js const routes = [ { path: '/admin', name: 'Admin', component: () => import('@/views/Admin.vue'), meta: { requiresAuth: true }, // 自定义元信息(标记需要权限) // 路由独享守卫 beforeEnter: (to, from, next) => { const isAdmin = localStorage.getItem('isAdmin') if (isAdmin) { next() } else { next('/403') // 无权限跳转到403页面 } } } ] |
(3)组件内守卫(影响当前组件)
--> import { onBeforeRouteEnter, onBeforeRouteLeave } from 'vue-router' // 进入组件前触发 onBeforeRouteEnter((to, from, next) => { // 注意:此时组件实例未创建,无法访问this next(vm => { // vm为组件实例,可访问vm.$data等 console.log('进入组件:', vm) }) }) // 离开组件前触发 onBeforeRouteLeave((to, from, next) => { // 示例:确认是否离开 if (confirm('确定要离开吗?未保存的数据将丢失')) { next() } else { next(false) } }) |
四、进阶优化:提升路由使用体验
1. 路由懒加载(优化首屏加载速度)
默认情况下,所有组件会在首屏一次性加载,导致打包体积过大。路由懒加载通过 “按需加载” 组件,减少首屏加载时间:
// 替换直接import为动态import const routes = [ { path: '/about', name: 'About', // 懒加载写法(推荐) component: () => import('@/views/About.vue') } ] // 可选:给懒加载组件分组(打包时合并为一个chunk) component: () => import(/* webpackChunkName: "about" */ '@/views/About.vue') |
2. 路由元信息(meta)
用于存储路由的额外信息(如标题、权限要求),在守卫中使用:
const routes = [ { path: '/about', name: 'About', component: () => import('@/views/About.vue'), meta: { title: '关于我们', // 页面标题 requiresAuth: false // 是否需要登录 } } ] // 在全局守卫中使用 router.beforeEach((to, from, next) => { if (to.meta.title) { document.title = to.meta.title } next() }) |
3. 滚动行为(页面跳转后滚动位置)
控制路由跳转后页面的滚动位置(如返回上一页保留滚动位置):
const router = createRouter({ history: createWebHistory(), routes, // 滚动行为配置 scrollBehavior(to, from, savedPosition) { if (savedPosition) { // 后退/前进时恢复滚动位置 return savedPosition } else { // 默认滚动到顶部 return { top: 0 } } } }) |
五、实战案例:实现登录权限控制
结合前面的知识点,实现一个完整的 “登录→权限校验→跳转” 流程:
- 登录页面(Login.vue):输入账号密码,登录成功后存储 token 到本地存储。
- 路由守卫:未登录时拦截需要权限的路由,跳转到登录页。
- 首页(Home.vue):登录后可访问,显示退出登录按钮。
关键代码:
// Login.vue 登录逻辑 const login = () => { // 模拟接口请求 setTimeout(() => { localStorage.setItem('token', 'fake-token-123') // 存储token router.push('/') // 登录成功跳转到首页 }, 1000) } // 首页退出登录 const logout = () => { localStorage.removeItem('token') // 清除token router.push('/login') // 跳转到登录页 } // 路由守卫(权限控制) router.beforeEach((to, from, next) => { const isLogin = localStorage.getItem('token') // 需要权限的路由(meta.requiresAuth为true) const requiresAuth = to.meta.requiresAuth if (requiresAuth && !isLogin) { next('/login') } else { next() } }) // 路由配置 const routes = [ { path: '/login', component: () => import('@/views/Login.vue') }, { path: '/', component: () => import('@/views/Home.vue'), meta: { requiresAuth: true } // 需要登录 } ] |
六、常见问题与避坑指南
- 路由跳转后页面不刷新?
原因:路由参数变化但组件未重新渲染(如/user/1→/user/2)。
解决:监听$route变化,或使用key强制刷新组件:
:key="$route.fullPath" /> |
- History 模式部署后刷新 404?
原因:History 模式依赖 HTML5 History API,刷新时服务器会请求该 URL,导致 404。
解决:配置服务器路由重定向(如 Nginx、Apache),将所有请求指向index.html。
- 路由守卫中 next () 调用时机?
必须调用next(),否则路由会卡住;避免多次调用next()(如在条件判断中遗漏else)。
- 懒加载组件报错?
检查路径是否正确(使用@别名时确保配置正确),Vue Router 4 需配合 Vue 3 使用。
七、总结
Vue Router 是 Vue 生态的核心插件,掌握其基础配置、动态路由、嵌套路由、路由守卫四大核心知识点,就能满足绝大多数 SPA 项目的路由需求。实际开发中,结合懒加载、滚动行为、元信息等优化技巧,可进一步提升项目性能和用户体验。
如果需要更复杂的场景(如路由缓存、多路由出口、Vuex/Pinia 结合路由),或 Vue 2 到 Vue 3 的迁移细节,欢迎在评论区交流!
附:参考资料
- Vue Router 官方文档(Vue 3)
- Vue Router 3.x 文档(Vue 2)
(注:文档部分内容可能由 AI 生成)