跳到主要内容

Vue Router 导航守卫

在 Vue.js 应用程序中,Vue Router 是管理路由的核心工具。导航守卫(Navigation Guards)是 Vue Router 提供的一种机制,允许你在路由跳转前、跳转中或跳转后执行特定的逻辑。通过导航守卫,你可以实现诸如用户权限验证、页面加载前数据获取等功能。

什么是导航守卫?

导航守卫是 Vue Router 提供的一组钩子函数,用于在路由跳转的不同阶段执行自定义逻辑。它们可以帮助你控制路由的跳转行为,例如阻止未授权的用户访问某些页面,或者在页面加载前获取必要的数据。

Vue Router 提供了三种类型的导航守卫:

  1. 全局守卫:作用于所有路由。
  2. 路由独享守卫:作用于特定路由。
  3. 组件内守卫:作用于特定组件。

接下来,我们将逐一介绍这些导航守卫的使用方法。


全局守卫

全局守卫是作用于所有路由的守卫,包括以下三种:

  • beforeEach:在路由跳转前执行。
  • beforeResolve:在路由跳转前,且在组件内守卫和异步路由组件解析后执行。
  • afterEach:在路由跳转后执行。

1. beforeEach

beforeEach 是最常用的全局守卫,通常用于用户权限验证。例如,你可以检查用户是否已登录,如果未登录则重定向到登录页面。

javascript
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

beforeResolvebeforeEach 之后执行,通常用于确保所有异步操作(如数据获取)已完成。

javascript
router.beforeResolve((to, from, next) => {
if (to.meta.requiresAuth) {
fetchData().then(() => next()); // 假设 fetchData 是一个异步函数
} else {
next();
}
});

3. afterEach

afterEach 在路由跳转后执行,通常用于日志记录或页面滚动到顶部。

javascript
router.afterEach((to, from) => {
console.log(`Navigated from ${from.path} to ${to.path}`);
window.scrollTo(0, 0); // 页面滚动到顶部
});

路由独享守卫

路由独享守卫是定义在路由配置中的守卫,仅作用于特定路由。它使用 beforeEnter 钩子。

javascript
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 在组件渲染前执行,此时组件实例尚未创建。

javascript
export default {
beforeRouteEnter(to, from, next) {
next(vm => {
// 通过 `vm` 访问组件实例
console.log(vm.someData); // 假设 someData 是组件的数据
});
}
};

2. beforeRouteUpdate

beforeRouteUpdate 在当前路由改变但组件复用时执行。

javascript
export default {
beforeRouteUpdate(to, from, next) {
this.fetchData(to.params.id); // 假设 fetchData 是一个获取数据的方法
next();
}
};

3. beforeRouteLeave

beforeRouteLeave 在离开当前路由前执行,通常用于提示用户保存未提交的表单。

javascript
export default {
beforeRouteLeave(to, from, next) {
if (this.isFormDirty) {
const confirmLeave = confirm('您有未保存的更改,确定要离开吗?');
if (confirmLeave) {
next();
} else {
next(false); // 取消导航
}
} else {
next();
}
}
};

实际案例

假设你正在开发一个博客应用,需要实现以下功能:

  1. 用户权限验证:未登录用户无法访问 /dashboard 页面。
  2. 数据预加载:在进入文章详情页前,预加载文章数据。
  3. 离开提示:用户在编辑文章时,如果未保存更改,提示用户确认离开。
javascript
// 全局守卫
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 中非常强大的功能,能够帮助你控制路由跳转的各个阶段。通过全局守卫、路由独享守卫和组件内守卫,你可以实现复杂的路由逻辑,如权限验证、数据预加载和离开提示等。


附加资源与练习

  1. 官方文档:阅读 Vue Router 官方文档 以了解更多高级用法。
  2. 练习:尝试在你的项目中实现以下功能:
    • 未登录用户无法访问 /profile 页面。
    • 在进入 /settings 页面时,预加载用户设置数据。
    • 用户在编辑个人资料时,如果未保存更改,提示用户确认离开。

通过实践,你将更好地掌握导航守卫的使用方法!