当前位置:首页 > 技术分析 > 正文内容

Vue-router中的路由守卫详解(vue3 路由守卫)

ruisui884个月前 (02-03)技术分析16

什么是路由守卫?

在 Vue.js 中,路由守卫是用来控制页面导航行为的函数。当我们在应用中切换路由时,路由守卫允许我们在路由改变之前或之后执行一些特定的逻辑。比如,我们可以用路由守卫来检查用户是否已登录,是否有权限访问某个页面,或者在离开当前页面之前提示用户保存未完成的工作等等。

这相当于vue中的生命周期钩子函数一样,在路由被操作的时候,会逐一触发这些路由守卫。将路由跳转过程细分为每一个小过程,让我们能在路由跳转过程中的每个状态,进行一系列的操作,这就是路由守卫。也可以称为路由的生命周期。

路由守卫的分类

在 Vue 3 中,路由守卫主要分为三类:全局的路由独享的组件内的

全局守卫

所谓全局守卫,就是所有的路由组件都会对这些函数进行调用,当任意路由发生改变的时候,都会调用这三个函数

全局前置守卫 (beforeEach)

全局前置守卫是在路由跳转之前执行的。你可以通过调用 router.beforeEach 方法注册一个或多个全局前置守卫。这些守卫会按照注册顺序依次执行,并且每个守卫都有机会中断导航过程。

import { createRouter, createWebHistory } from 'vue-router';

const router = createRouter({
  history: createWebHistory(),
  routes: [
    // 你的路由配置
  ],
});

router.beforeEach((to, from, next) => {
    console.log('全局前置守卫')
    next(); 
  }
});

export default router;

全局解析守卫 (beforeResolve)

全局解析守卫类似于前置守卫,但它的主要用途是在导航被确认之后,解析组件之前被调用。这可以用于在导航之前解析数据,如果不需要在导航确认之前就阻止导航,那么可以使用此守卫。

router.beforeResolve((to, from, next) => { 
    console.log('全局解析守卫') 
    next() 
})

全局后置守卫 (afterEach)

全局后置守卫会在导航完成后被调用。它们不接受 next 函数也不可以中断导航,但是可以用来做一些清理工作或者修改状态。

router.afterEach((to, from, next) => { 
    console.log('全局后置守卫') 
    next() 
})

路由独享守卫

路由独享守卫是一种特殊的导航守卫,它只应用于单个路由或一组路由。这种守卫可以让你在路由配置中直接定义,而不像全局守卫那样需要在路由器实例上注册。路由独享守卫允许你针对特定的路由实施一些逻辑,例如验证用户是否有权限访问某个页面。

它与全局前置守卫中的全局前置守卫 beforeEach 相似,但它是特定于每个路由的。

import { createRouter, createWebHistory } from 'vue-router'; 

const router = createRouter({ 
history: createWebHistory(), 
routes: [ 
    { 
        path: '/admin', 
        name: 'admin', 
        component: () => import('@/views/Home.vue'), 
        beforeEnter: (to, from, next) => { 
            // 判断是否登录 
            if (已登录) { 
                next();
            } else { 
                next('/login'); 
            } 
        }, 
    }, 
    // 更多路由... 
], 
});

组件内守卫

除了全局守卫和路由独享守卫之外,还可以在组件内部定义守卫。组件内的守卫主要用于控制组件自身的生命周期,以及在组件加载或更新时执行一些特定的操作。这些守卫包括 beforeRouteEnter、beforeRouteUpdate 和 beforeRouteLeave

beforeRouteEnter

beforeRouteEnter 守卫是在组件被创建之前被调用的,也就是在组件实例还未创建时。因此,在这个守卫里不能访问到 this(即当前组件实例),因为它还未被创建。你可以传递一个回调给 next 函数来访问组件实例。

beforeRouteEnter(to, from, next) {
    // 由于 `this` 在 `beforeRouteEnter` 钩子中不可用,
    // 所以必须把回调函数传给 `next`。
    next(a => {
      console.log(a);
    });
  },

beforeRouteUpdate

beforeRouteUpdate 守卫会在当前路由改变,但是该组件被复用时调用。例如,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间导航的时候,同一个 Foo 组件实例会被复用,而这个守卫就会被调用。

 beforeRouteUpdate(to, from, next) {
    // 更新组件的状态
    this.someData = to.params.id;
    next();
  },

beforeRouteLeave

beforeRouteLeave 守卫在导航离开该组件的对应路由时被调用。它可用于在离开路由前进行一些操作,比如保存用户编辑的内容或询问用户是否确定离开。

  beforeRouteLeave(to, from, next) {
    // 询问用户是否真的要离开
    const answer = window.confirm('Do you really want to leave? ');
    if (answer) {
      next(); // 确认离开
    } else {
      next(false); // 取消离开
    }
  },

补充

router.beforeEach((to, from, next) => {
    if (已登录) { 
        next();
    } else { 
        next('/login'); 
    } 
  }
});

这种情况下会出现空白页面,因为当你进入登录页面的时候,我们还是处于未登录状态,会出现一直循环,造成死循环。所以我们应该要修改一下判断条件。

router.beforeEach((to, from, next) => {
    if (已登录||to.name==='login') { 
        next();
    } else { 
        next('/login'); 
    } 
  }
});

路由守卫回调参数

to:即将要进入的目标路由对象;

from:即将要离开的路由对象;

next:涉及到next参数的钩子函数,必须调用next()方法来resolve这个钩子,否则路由会中断在这,不会继续往下执行

  • next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是confirmed(确认的)。
  • next( false )中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到from路由对应的地址。
  • next( ' / ')或者next({ paht:' / ' }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。可传递的参数可以是router-link标签中的to属性参数或router.push中的选项
  • next( error ):如果传入next的参数是一个Error实例,则导航会被终止且该错误会被传递给router.onError()注册过的回调。

完整的导航解析流程

  1. 导航被触发。
  2. 在离开的组件里调用 beforeRouteLeave 守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 。
  5. 在路由配置里调用 beforeEnter。
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter。
  8. 调用全局的 beforeResolve 守卫 。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

总结

路由守卫在 Vue.js 应用中是一个非常重要的工具,它允许我们在路由导航的各个阶段插入自定义逻辑,从而确保应用的安全性、数据完整性和用户体验。通过正确使用路由守卫,你可以轻松地实现鉴权、数据预加载、防止数据丢失等常见需求。无论是全局守卫、路由独享守卫还是组件内守卫,它们都为你提供了灵活而强大的导航控制能力。


附:前端面试资料无偿分享,八股文及场景题

有想要的朋友:点赞后,私信【前端】免费领取完整版

扫描二维码推送至手机访问。

版权声明:本文由ruisui88发布,如需转载请注明出处。

本文链接:http://www.ruisui88.com/post/804.html

分享给朋友:

“Vue-router中的路由守卫详解(vue3 路由守卫)” 的相关文章

vue组件间的九种通信方式

前言Vue组件实例间的作用域是相互独立的,而通常一个页面是由很多个组件构成,这些组件可能又嵌套了组件,形成了一个关系网图,它们的关系可能是像下图中一样,大致分为两种使用场景,父子组件间通信和非父子组件间通信,父子组件间通信又分为直接父子关系和间接父子关系。vue提供了多种通信方法,针对不同的通信需求...

使用cgroup限制进程资源

这里使用containerd项目中的cgroup包来实现进程资源限制。先写一个耗费一个CPU并且一秒增加10m内存的测试进程package mainimport ( "fmt" "math/rand" "time")func main() { go f...

10款超牛Vim插件,爱不释手了

我是一个忠实的Vim编辑器用户,从事开发工作多年,我一直都非常喜欢使用Vim。轻量、便捷,而且,熟悉了Vim相关的快捷键之后,效率能够成倍的提升。除了这些之外,Vim像很多知名的IDE、编辑器一样,也支持插件配置,通过这些插件,可以实现更多高级、高效的操作。今天,就来给大家分享10个我特别喜欢的Vi...

HTML5+眼球追踪?黑科技颠覆传统手机体验

今天,iH5工具推出一个新的神秘功能——眼动追踪,可以通过摄像头捕捉观众眼球活动!为了给大家具体演示该功能的使用,我做了一个案例,供大家参考。实际效果如下:案例比较简单,就是通过眼动功能获取视觉焦点位置,剔除用户看中的牌。现在,舞台的属性中多了一个“启用眼动”的选项,另外,还多了一个“启用摄像头”的...

双子座应用程序推出模型切换器以在Android上访问2.0

#头条精品计划# 快速导读谷歌推出了Gemini 2.0 Flash实验版,现已在其安卓应用中可用,之前仅在gemini.google.com网站上提供。新版本的15.50包含模型切换器,用户可以在设置中选择不同模型,包括1.5 Pro、1.5 Flash和2.0 Flash实验版。谷歌提醒,2.0...

2024年,不断突破的一年

迈凯伦F1车队不久前拿下了2024年度总冠军,距离上一次还是二十几年前。在此期间,另一领域内,一个充满革新活力的腕表品牌——RICHARD MILLE理查米尔,正不断发展,与F1运动、帆船、古董车展等领域,共享着对速度与极限的无尽向往。RICHARD MILLE的发展与F1车手们在赛道上的卓越表现交...