Vue Router 导航守卫
在 Vue.js 应用程序中,Vue Router 是管理路由的核心工具。导航守卫(Navigation Guards)是 Vue Router 提供的一种机制,允许你在路由跳转前、跳转中或跳转后执行特定的逻辑。通过导航守卫,你可以实现诸如用户权限验证、页面加载前数据获取等功能。
什么是导航守卫?
导航守卫是 Vue Router 提供的一组钩子函数,用于在路由跳转的不同阶段执行自定义逻辑。它们可以帮助你控制路由的跳转行为,例如阻止未授权的用户访问某些页面,或者在页面加载前获取必要的数据。
Vue Router 提供了三种类型的导航守卫:
- 全局守卫:作用于所有路由。
- 路由独享守卫:作用于特定路由。
- 组件内守卫:作用于特定组件。
接下来,我们将逐一介绍这些导航守卫的使用方法。
全局守卫
全局守卫是作用于所有路由的守卫,包括以下三种:
beforeEach
:在路由跳转前执行。beforeResolve
:在路由跳转前,且在组件内守卫和异步路由组件解析后执行。afterEach
:在路由跳转后执行。
1. beforeEach
beforeEach
是最常用的全局守卫,通常用于用户权限验证。例如,你可以检查用户是否已登录,如果未登录则重定向到登录页面。
router.beforeEach((to, from, next) => {
const isAuthenticated = checkAuth(); // 假设这是一个检查用户是否登录的函数
if (to.path !== '/login' && !isAuthenticated) {
next('/login'); // 重定向到登录页面
} else {
next(); // 允许跳转
}
});
to
:目标路由对象。from
:当前路由对象。next
:一个函数,调用它来继续路由跳转。你可以传递一个路径(如next('/login')
)来重定向,或者直接调用next()
来允许跳转。
2. beforeResolve
beforeResolve
在 beforeEach
之后执行,通常用于确保所有异步操作(如数据获取)已完成。
router.beforeResolve((to, from, next) => {
if (to.meta.requiresAuth) {
fetchData().then(() => next()); // 假设 fetchData 是一个异步函数
} else {
next();
}
});
3. afterEach
afterEach
在路由跳转后执行,通常用于日志记录或页面滚动到顶部。
router.afterEach((to, from) => {
console.log(`Navigated from ${from.path} to ${to.path}`);
window.scrollTo(0, 0); // 页面滚动到顶部
});
路由独享守卫
路由独享守卫是定义在路由配置中的守卫,仅作用于特定路由。它使用 beforeEnter
钩子。
const routes = [
{
path: '/dashboard',
component: Dashboard,
beforeEnter: (to, from, next) => {
const isAdmin = checkAdmin(); // 假设这是一个检查用户是否为管理员的函数
if (!isAdmin) {
next('/403'); // 重定向到 403 页面
} else {
next();
}
}
}
];
组件内守卫
组件内守卫是定义在 Vue 组件中的守卫,包括以下三种:
beforeRouteEnter
:在组件渲染前执行。beforeRouteUpdate
:在当前路由改变但组件复用时执行。beforeRouteLeave
:在离开当前路由前执行。
1. beforeRouteEnter
beforeRouteEnter
在组件渲染前执行,此时组件实例尚未创建。
export default {
beforeRouteEnter(to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
console.log(vm.someData); // 假设 someData 是组件的数据
});
}
};
2. beforeRouteUpdate
beforeRouteUpdate
在当前路由改变但组件复用时执行。
export default {
beforeRouteUpdate(to, from, next) {
this.fetchData(to.params.id); // 假设 fetchData 是一个获取数据的方法
next();
}
};
3. beforeRouteLeave
beforeRouteLeave
在离开当前路由前执行,通常用于提示用户保存未提交的表单。
export default {
beforeRouteLeave(to, from, next) {
if (this.isFormDirty) {
const confirmLeave = confirm('您有未保存的更改,确定要离开吗?');
if (confirmLeave) {
next();
} else {
next(false); // 取消导航
}
} else {
next();
}
}
};
实际案例
假设你正在开发一个博客应用,需要实现以下功能:
- 用户权限验证:未登录用户无法访问
/dashboard
页面。 - 数据预加载:在进入文章详情页前,预加载文章数据。
- 离开提示:用户在编辑文章时,如果未保存更改,提示用户确认离开。
// 全局守卫
router.beforeEach((to, from, next) => {
if (to.path === '/dashboard' && !isAuthenticated()) {
next('/login');
} else {
next();
}
});
// 路由独享守卫
const routes = [
{
path: '/article/:id',
component: ArticleDetail,
beforeEnter: (to, from, next) => {
fetchArticle(to.params.id).then(() => next());
}
}
];
// 组件内守卫
export default {
data() {
return {
isFormDirty: false
};
},
beforeRouteLeave(to, from, next) {
if (this.isFormDirty) {
const confirmLeave = confirm('您有未保存的更改,确定要离开吗?');
if (confirmLeave) {
next();
} else {
next(false);
}
} else {
next();
}
}
};
总结
导航守卫是 Vue Router 中非常强大的功能,能够帮助你控制路由跳转的各个阶段。通过全局守卫、路由独享守卫和组件内守卫,你可以实现复杂的路由逻辑,如权限验证、数据预加载和离开提示等。
附加资源与练习
- 官方文档:阅读 Vue Router 官方文档 以了解更多高级用法。
- 练习:尝试在你的项目中实现以下功能:
- 未登录用户无法访问
/profile
页面。 - 在进入
/settings
页面时,预加载用户设置数据。 - 用户在编辑个人资料时,如果未保存更改,提示用户确认离开。
- 未登录用户无法访问
通过实践,你将更好地掌握导航守卫的使用方法!