首页 > 其他分享 >Vue Router 5个导航守卫(详解)

Vue Router 5个导航守卫(详解)

时间:2024-04-06 12:58:45浏览次数:23  
标签:Vue next 守卫 详解 router 组件 Router 导航 路由

文章目录


导航守卫

vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航
注意:参数或查询的改变并不会触发进入/离开的导航守卫,你可以通过观察 $route 对象来应对这些变化,或使用 beforeRouteUpdate 的组件内守卫。

全局前置守卫

使用 router.beforeEach 注册一个全局前置守卫

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫 resolve 完之前一直处于 等待中。

  • to:: 即将要进入的目标 路由对象
  • from: 当前导航正要离开的路由
  • next:
    • next(): 进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。
    • next(false): 中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。
    • next('/') 或者 next({ path: '/' }): 跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: true、name: ‘home’ 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
    • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保 next 函数在任何给定的导航守卫中都被严格调用一次。它可以出现多于一次,但是只能在所有的逻辑路径都不重叠的情况下,否则钩子永远都不会被解析或报错

用户未能验证身份时重定向到 /login 的示例:

// BAD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  // 如果用户未能验证身份,则 `next` 会被调用两次
  next()
})
// GOOD
router.beforeEach((to, from, next) => {
  if (to.name !== 'Login' && !isAuthenticated) next({ name: 'Login' })
  else next()
})

全局解析守卫

在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用

router.beforeResolve((to, from, next) => { } )

全局后置钩子

全局后置钩子,然而和守卫不同的是,这些钩子不会接受 next 函数也不会改变导航本身

router.afterEach((to, from) => {
  // ...
})

路由独享的守卫

在路由配置上直接定义 beforeEnter 守卫

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

守卫与全局前置守卫的方法参数是一样的

组件内的守卫

在路由组件内直接定义以下路由导航守卫:

  • beforeRouteEnter
  • beforeRouteUpdate (2.2 新增)
  • beforeRouteLeave
const Foo = { 
	termplate: `....`,
	beforeRouteEnter(to, from, next) { 
		// 在渲染该组件的对应路由被 confirm 前调用
	    // 不!能!获取组件实例 `this`
	    // 因为当守卫执行前,组件实例还没被创建
	},
	 beforeRouteUpdate(to, from, next) {
	    // 在当前路由改变,但是该组件被复用时调用
	    // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
	    // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
	    // 可以访问组件实例 `this`
  },
	 beforeRouteLeave(to, from, next) {
	    // 导航离开该组件的对应路由时调用
	    // 可以访问组件实例 `this`
  }
 }

beforeRouteEnter 守卫 不能 访问 this,因为守卫在导航确认前被调用,因此即将登场的新组件还没被创建。

可以通过传一个回调给 next来访问组件实例。在导航被确认的时候执行回调,并且把组件实例作为回调方法的参数。

beforeRouteEnter (to, from, next) {
  next(vm => {
    // 通过 `vm` 访问组件实例
  })
}

注意 beforeRouteEnter 是支持给 next 传递回调的唯一守卫。对于 beforeRouteUpdatebeforeRouteLeave 来说,this 已经可用了,所以不支持传递回调,因为没有必要了。

beforeRouteUpdate (to, from, next) {
  // just use `this`
  this.name = to.params.name
  next()
}

这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消

beforeRouteLeave (to, from, next) {
  const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
  if (answer) {
    next()
  } else {
    next(false)
  }
}

完整的导航解析流程

  • 导航被触发。
  • 在失活的组件里调用 beforeRouteLeave 守卫。
  • 调用全局的 beforeEach 守卫。
  • 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  • 在路由配置里调用 beforeEnter。
  • 解析异步路由组件。
  • 在被激活的组件里调用 beforeRouteEnter。
  • 调用全局的 beforeResolve 守卫 (2.5+)。
  • 导航被确认。
  • 调用全局的 afterEach 钩子。
  • 触发 DOM 更新。
  • 调用 beforeRouteEnter 守卫中传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入。

标签:Vue,next,守卫,详解,router,组件,Router,导航,路由
From: https://blog.csdn.net/weixin_44216637/article/details/137424845

相关文章

  • Vue.js自定义指令
    除了默认设置的核心指令(v-model和v-show),Vue也允许注册自定义指令。下面我们注册一个全局指令v-focus,该指令的功能是在页面加载时,元素获得焦点:<body><divclass="app"><span>页面载入时,input元素自动获取焦点:</span><inputv-focust......
  • 游戏攻略|基于Springboot和vue的游戏分享平台系统设计与实现(源码+数据库+文档)
    游戏攻略分享平台目录基于Springboot的在线考试管理系统设计与实现一、前言二、系统设计三、系统功能设计 1、前台:2、后台5.2.1管理员功能模块四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道......
  • vue3的ref和reactive函数
    在vue3中需要引入ref和reactive函数对变量进行声明 首先引入ref,reactive函数,vue3不同于vue2的是,变量的声明需要写在setup函数中,(vue2是直接写在data函数中)其中ref主要是对一些基础数据变量声明,如string,number,boolean,而reactive则是对复杂的,入对象进行声明最后,定义......
  • Vue2 —— 学习(一)
    (二)简单案例1.实现过程容器设置Vue实例设置 2.实现结果 3.注意事项(三)Vue插件​编辑三、Vue模板语法 (一)插值语法{{}}:(二)指令语法v-四、Vue数据绑定  (一)单向数据绑定:(二)双向数据绑定: 五、el和data的两种写法(一)查看实例(二)el:1.第一种写法:直接写2.第......
  • 练手项目层初阶1—《详解静态版本——通讯录管理系统》
    文章目录......
  • 虚拟内存知识详解
    虚拟内存单片机的CPU是直接操作内存的「物理地址」在这种情况下,要想在内存中同时运行两个程序是不可能的操作系统是如何解决这个问题呢?关键的问题是这两个程序都引用了绝对物理地址,而这正是我们最需要避免的。可以把进程所使用的地址「隔离」开来,即让操作系统为每......
  • 初识Vue
    1.1-网站交互方式Web网站交互方式:1、单页应用程序(SPA,Signal-pageApplication)2、多页应用程序(MPA,Multi-pageApplication)1.1.1-单页应用程序单页应用程序,一张Web页面的应用单页应用程序是加载单个HTML页面并在用户与应用程序交互时,动态更新该页面的Web应用程序浏览......
  • ssm+vue的精准扶贫管理。Javaee项目,ssm vue前后端分离项目。
    演示视频:ssm+vue的精准扶贫管理。Javaee项目,ssmvue前后端分离项目。项目介绍:采用M(model)V(view)C(controller)三层体系结构,通过Spring+SpringMvc+Mybatis+Vue+Maven来实现。MySQL数据库作为系统数据储存平台,实现了基于B/S结构的Web系统。界面简洁,操作简单。......
  • 详解 Redis 在 Ubuntu 系统上的安装
    在Ubuntu20.04安装Redis1.先切换到root用户在Ubuntu20.04中,可以通过以下步骤切换到root用户:输入以下命令,以root用户身份登录:sudosu-按回车键,并输入当前用户的密码(即具有sudo权限的用户的密码)如果密码正确,将会切换到root用户,并且提示符会变为以r......
  • Redis各个方面入门详解
    目录一、Redis介绍二、分布式缓存常见的技术选型方案三、Redis和Memcached的区别和共同点四、缓存数据的处理流程五、Redis作为缓存的好处六、Redis常见数据结构以及使用场景七、Redis单线程模型八、Redis给缓存数据设置过期时间九、Redis判断数据过期的原理十......