1.概念

2.种类

2.1 全局路由守卫

2.1.1 beforEach

2.1.2 afterEach

2.1.3 beforeResolve

2.2 组件内守卫

2.2.1 beforeRouteEnter

2.2.2 beforeRouteUpdate

2.2.3 beforeRouteLeave

1.概念

路由守卫是Vue Router提供的一种导航控制机制,可以在导航过程中进行拦截和处理操作。

2.种类

  1. 全局路由守卫:整个应用层面控制路由跳转,不依赖具体组件。
  2. 组件内的路由守卫:写在某个组件内部,只对该组件的路由跳转生效。

2.1 全局路由守卫

常见的全局路由守卫有三种:beforeEach、afterEach、beforeResolve

2.1.1 beforEach

触发时机:路由跳转前触发,一般用于登录校验和权限的校验。语法:beforeEach((to, from, next)。to表示要跳转到的页面,from表示跳转前的页面页面,next表示是否允许跳转,或者重定向。

// router/index.js
router.beforeEach((to, from, next) => {
  const isLoggedIn = !!localStorage.getItem('token');
// 判断是否已经登录
  if (to.meta.requiresAuth && !isLoggedIn) {
// 重定向到登录页
    next('/login');
  } else {
// 放行
    next();
  }
});
2.1.2 afterEach

触发时机:路由跳转后触发,一般用于埋点、页面标题设置。语法:afterEach((to, from)。

router.afterEach((to, from) => {
  console.log('[afterEach] 跳转完成', { from: from.fullPath, to: to.fullPath });
});
2.1.3 beforeResolve

触发时机:在所有组件内守卫和异步路由组件解析完后触发,一般用于关闭Loading动画。语法:beforeResolve((to, from, next)。

// 假设你在入口文件里把 <LoadingBar> 挂到全局
router.beforeResolve(() => {
  // 所有异步组件、所有组件内守卫都处理完了
  // 可以结束 loading 动画
  window.$loadingBar.finish();
});

2.2 组件内守卫

常见的组件内守卫有三种:beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave。

2.2.1 beforeRouteEnter

触发时机:进入该组件前触发,并且不能访问 this,需用 next(vm => {})去获取组件实例语法:beforeRouteEnter((to, from, next)。

// 组件中
export default {
  beforeRouteEnter(to, from, next) {
    // 不能访问 this,使用回调获取组件实例vm
    next(vm => {
      vm.fetchData();
    });
  },
}
2.2.2 beforeRouteUpdate

触发时机:路由参数变化但复用组件时触发,比如 /user/1 → /user/2。语法:beforeRouteUpdate((to, from, next)。

export default{
// 路由参数变化但组件复用时触发
  beforeRouteUpdate(to, from, next) {
    console.log(`[beforeRouteUpdate] ${from.params.id} → ${to.params.id}`);
    this.fetchUser(to.params.id); // 用新 id 重新拉数据
    next();                       // 别忘了放行
  },
}
2.2.3 beforeRouteLeave

触发时机:离开组件时触发,一般用于保存未提交的表单数据。beforeRouteLeave((to, from, next)。

export default {
 beforeRouteLeave(to, from, next) {
    const answer = window.confirm('你还有未保存的内容,确定离开吗?');
    if (answer) next();
    else next(false);
  }
 }
}

更多推荐