Vue Router 是 Vue.js 官方的路由管理器,用于实现单页应用(SPA)的路由功能。它基于组件化的设计,提供了路由导航、路由参数、路由守卫、路由懒加载等核心功能,使开发者能够构建复杂的前端路由系统。以下是对 Vue Router 的详细解析:
一、核心概念
1. 路由配置与匹配
Vue Router 通过 routes
数组定义路由配置,每个路由映射到一个组件:
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/user/:id', // 动态路由参数
name: 'User',
component: User
},
{
path: '/about',
redirect: '/info' // 路由重定向
}
];
- 动态路由参数:使用
:param
定义,如/user/:id
,可通过$route.params.id
访问。 - 嵌套路由:通过
children
配置子路由,实现组件嵌套。 - 路由别名与命名路由:使用
alias
和name
简化路由使用。
2. 路由导航
Vue Router 提供两种导航方式:
声明式导航:使用 <router-link>
组件:
<router-link to="/home">Home</router-link>
编程式导航:通过 this.$router
方法:
1. push(location)
作用: 向历史堆栈添加新记录并跳转
参数:
path
字符串:如'/about'
命名路由对象:
{ name: 'user', params: { id: 123 } }
完整配置对象:
{ path, query, hash }
2. replace(location)
区别: 不新增历史记录,直接替换当前记录
用途: 防止用户点返回键回到跳转前的页面
3. go(n)
功能: 沿历史记录前进/后退N步
// 跳转
this.$router.push('/home');
this.$router.push({ name: 'User', params: { id: 1 } });
// 替换当前路由
this.$router.replace('/about');
// 后退/前进
this.$router.go(-1);
3. 路由守卫
用于控制导航的权限和行为,分为全局守卫、路由独享守卫和组件内守卫:
- 全局守卫:统一处理登录、权限、日志等全局逻辑。
- 路由独享守卫:针对特定路由的精细化控制(如管理员页面)。
- 组件内守卫:处理组件生命周期相关的导航逻辑(如数据加载、离开确认)。
// 全局前置守卫
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !isAuthenticated()) {
next('/login'); // 未登录时重定向到登录页
} else {
next(); // 继续导航
}
});
// 路由独享守卫
const routes = [
{
path: '/admin',
component: Admin,
beforeEnter: (to, from, next) => {
// 仅管理员可访问
}
}
];
// 组件内守卫
export default {
beforeRouteEnter(to, from, next) {
// 在渲染该组件的对应路由被 confirm 前调用
},
beforeRouteUpdate(to, from, next) {
// 在当前路由改变,但是该组件被复用时调用
}
};
4. 路由元信息(meta)
在路由配置中添加自定义数据,用于权限控制、页面标题等:
const routes = [
{
path: '/dashboard',
component: Dashboard,
meta: { requiresAuth: true, title: '仪表盘' }
}
];
// 获取元信息
router.beforeEach((to, from, next) => {
document.title = to.meta.title || '默认标题';
next();
});
二、高级特性
1. 路由懒加载
按需加载路由组件,提高应用性能:
// 使用动态 import
const User = () => import('./views/User.vue');
const routes = [
{
path: '/user',
component: User
}
];
2. 路由模式
Vue Router 支持两种路由模式:
- hash 模式(默认):URL 中带
#
,如http://example.com/#/home
,兼容性好。 - history 模式:使用 HTML5 History API,URL 更美观,如
http://example.com/home
,但需要服务器配置支持:
const router = new VueRouter({
mode: 'history',
routes
});
补充:
一、工作原理
hash模式
- 原理:通过URL中的
#
符号及后面的哈希值实现路由。例如:http://example.com/#/home
。 - 关键点:
#
后的内容不会被发送到服务器,仅由前端处理。- 监听
window.onhashchange
事件,触发路由更新。
- 特点:
- 页面跳转时不会触发全页刷新,仅更新哈希部分。
- 天然支持老旧浏览器(如IE8)。
- 原理:通过URL中的
history模式
- 原理:使用HTML5的
History API
(pushState
和replaceState
)修改URL,无需#
符号。例如:http://example.com/home
。 - 关键点:
- URL直接反映路径,与后端路由解耦。
- 依赖浏览器的历史记录栈,通过
popstate
事件监听后退/前进操作。
- 特点:
- 需服务器配置支持,确保非根路径请求返回同一HTML文件(如
index.html
。 - 现代浏览器支持良好,但低版本浏览器(如IE9以下)不兼容
- 需服务器配置支持,确保非根路径请求返回同一HTML文件(如
- 原理:使用HTML5的
二、核心区别
特性 | hash模式 | history模式 |
---|---|---|
URL格式 | http://example.com/#/home |
http://example.com/home |
刷新行为 | 刷新不影响页面状态 | 需服务器配置,否则可能返回40468 |
SEO友好性 | 不友好,搜索引擎可能忽略# 后内容 |
友好,URL可被正常索引137 |
浏览器兼容性 | 支持所有浏览器(包括IE8) | 仅支持现代浏览器(IE10+)67 |
服务器依赖 | 无需特殊配置 | 需配置重定向(如Nginx、Apache)38 |
传参方式 | 通过# 后字符串拼接 |
支持路径参数和state 对象传递6 |
三、适用场景
选择hash模式
- 场景:快速开发、无需SEO、兼容性要求高、后端无法配合配置。
- 优势:简单易用,开箱即用,无服务器依赖。
选择history模式
- 场景:需要SEO优化、追求URL美观、项目对兼容性要求不高。
- 优势:URL简洁,符合标准Web语义,利于分享和搜索引擎抓取
四、配置示例
hash模式配置
const router = new VueRouter({ mode: 'hash', // 默认模式 routes: [ { path: '/home', component: Home }, { path: '/about', component: About } ] });
2、history模式配置
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/home', component: Home },
{ path: '/about', component: About }
],
scrollBehavior: () => ({ y: 0 }) // 示例:滚动行为
});
服务器配置示例(Nginx)(与history联合使用)
location / {
try_files $uri $uri/ /index.html;
}
五、常见问题
history模式刷新报404
- 原因:服务器未配置重定向,无法处理非根路径请求。
- 解决方案:配置服务器将所有请求重定向到
index.html
(如Nginx的try_files
指令)。
hash模式URL丑陋
- 解决方法:使用
history
模式或通过base
配置缩短哈希路径。
- 解决方法:使用
低版本浏览器兼容
- 应对:若需支持IE9以下,优先选用hash模式。
3. 导航守卫执行流程
- 触发路由跳转。
- 调用全局
beforeEach
守卫。 - 调用路由配置中的
beforeEnter
守卫。 - 调用组件内的
beforeRouteEnter
守卫。 - 解析异步路由组件。
- 调用全局
beforeResolve
守卫。 - 导航确认。
- 调用全局
afterEach
钩子。 - 更新 DOM。
三、常见应用场景
1. 权限控制
通过全局守卫实现登录验证:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth) {
if (localStorage.getItem('token')) {
next();
} else {
next({ name: 'Login' });
}
} else {
next();
}
});
2. 路由过渡动画
结合 Vue 的过渡系统实现路由切换动画:
<transition name="fade">
<router-view></router-view>
</transition>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
3. 404 页面处理
使用通配符路由匹配所有未定义的路径:
const routes = [
{
path: '*',
component: NotFound
}
];
四、与 Vue 3 的集成
Vue Router 4.x 是 Vue 3 的官方路由库,主要变化包括:
使用 createRouter
和 createWebHistory
创建路由实例:
import { createRouter, createWebHistory } from 'vue-router';
const router = createRouter({
history: createWebHistory(),
routes
});
组合式 API 支持:
import { useRouter, useRoute } from 'vue-router';
export default {
setup() {
const router = useRouter();
const route = useRoute();
const goToUser = () => {
router.push({ name: 'User', params: { id: 1 } });
};
return {
goToUser
};
}
};