Vue.js 学习笔记十三:Vue Router 之导航守卫

2023-11-01

目录

导航守卫

全局前置守卫

全局后置钩子

路由独享的守卫

组件内的守卫



导航守卫

我们来考虑一个需求:在一个 SPA 应用中, 如何改变网页的标题呢?

网页标题是通过 <title> 来显示的,但是 SPA 只有一个固定的 HTML,切换不同的页面时,标题并不会改变。但是我们可以通过 JavaScript 来修改 <title> 的内容。

 window.document.title = '新的标题'

那么在 Vue 项目中, 在哪里修改?什么时候修改比较合适呢?

普通的修改方式:

我们比较容易想到的修改标题的位置是每一个路由对应的组件 .vue 文件中。通过 mounted 声明周期函数, 执行对应的代码进行修改即可。

但是当页面比较多时, 这种方式不容易维护(因为需要在多个页面执行类似的代码)。

有没有更好的办法呢?使用导航守卫即可。

什么是导航守卫?

Vue Router 提供的导航守卫主要用来监听监听路由的进入和离开的。

Vue Router 提供了 beforeEachafterEach 的钩子函数,它们会在路由即将改变前和改变后触发。

全局前置守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:

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

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

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

每个守卫方法接收三个参数:

  • to: Route:即将要进入的路由对象。

  • from: Route:当前导航正要离开的路由对象。

  • next: Function:一定要调用该方法来 resolve 这个钩子。执行效果依赖 next 方法的调用参数。

    • next():进行管道中的下一个钩子。如果全部钩子执行完了,则导航的状态就是 confirmed (确认的)。

    • next(false):中断当前的导航。如果浏览器的 URL 改变了 (可能是用户手动或者浏览器后退按钮),那么 URL 地址会重置到 from 路由对应的地址。

    • next('/') 或者 next({ path: '/' }):跳转到一个不同的地址。当前的导航被中断,然后进行一个新的导航。你可以向 next 传递任意位置对象,且允许设置诸如 replace: truename: 'home' 之类的选项以及任何用在 router-linkto proprouter.push 中的选项。

    • next(error):(2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

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

这里我们利用beforeEach 来完成标题的修改。

首先,我们可以在钩子当中定义一些标题,可以利用 meta (路由元信息)来定义。

const routes = [	
     {
        path: '/home',  
		name: 'Home',
    	component: Home,	
		meta: {
			title: '首页'
		}
      },
      {
        path: '/about',
        name: 'About',
        component: About,
            meta: {
                title: '关于'
            }
      }
]

其次,利用导航守卫,修改我们的标题。

router.beforeEach((to, from, next) => {
  	window.document.title = to.meta.title
	next()
})

这里还有一个在用户未认证(未登录或认证过期)时,重定向到 /login 的示例:

router.beforeEach((to, from, next) => {
   if (to.name !== 'Login' && !isAuthenticated) {
       next({name: 'Login'})
   } else {
       next()
   }
 })

全局后置钩子

你也可以使用 afterEach 注册全局后置钩子 ,但不需要主动调用 next() 函数。

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

// 修改我们的标题
router.afterEach((to) => {
  window.document.title = to.meta.title
})

路由独享的守卫

你可以在路由配置上直接定义 beforeEnter 守卫,只有当进入这个路由时才会调用的,这些守卫与全局前置守卫的方法参数是一样的。

const routes = [    
      {
         path: '/home',  
         name: 'Home',
         component: Home,    
         meta: {
             title: '首页'
         },
         beforeEnter: (to, from, next) => {
           // ...
         }
       },
       {
         path: '/about',
         name: 'About',
         component: About,
             meta: {
                 title: '关于'
             }
       }
 ]

组件内的守卫

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

  • beforeRouteEnter

  • beforeRouteUpdate

  • beforeRouteLeave

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

这三个守卫是写在组件里,beforeRouteEnter 守卫不能访问 this,因为守卫在导航确认前被调用,因此即将进入的新组件还没被创建。

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

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('有未保存的更改,你真的想离开吗?')
   if (answer) {
     next()
   } else {
     next(false)
   }
 }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Vue.js 学习笔记十三:Vue Router 之导航守卫 的相关文章

  • Redis(7)-主从复制

    redis主从复制 1 主从复制 1 复制原理 2 哨兵模式 那么如何选择需要的新服务器呢 1 主从复制 就是指将主机数据更新后根据配置和策略 自动同步到备机master slave 其中master以写为主 slave以读为主 用处 读写
  • pkill(1) command

    文章目录 1 命令简介 2 命令格式 3 选项说明 4 常用示例 参考文献 大咖好呀 我是恋喵大鲤鱼 鄙人第二本开源书籍 后台开发命令365 上线啦 欢迎大家协同共建 1 命令简介 pkill process kill 杀死某一类进程 pk
  • FPGA之RAM详解,单口RAM的使用

    单口RAM IP练习 RAM在FPGA设计当中应用非常广泛 其种类有单口RAM 伪双口RAM 真双口RAM 但就实际项目开发而言 伪双口RAM应该是使用频率最多的 大家在学习实践的时候 也完全可以多做些对比 这样有更助于消化理解后加以灵活应

随机推荐

  • 矩阵乘以它的转置

    矩阵乘以它的转置 AA T A A T A A A 2即矩阵A乘以A的转置等于A的行列式的平方 明显不等于啦 1 2的矩阵转置矩阵为2 1 那么1 2的矩阵乘以2 1的转置矩阵得到一个1 1的矩阵 而2 1的转置矩阵乘以1 2的矩阵得到一个
  • 基于Dragonboard 410c的指纹锁(七)

    继续研究fingerprint在Android中的添加 上篇中HAL层的实现算是找到了 但是不知道是不是真的是这个 也不知道有没有被应用 既然驱动没有 那就往上看吧 开机时会开启各种服务 我们从开始启动指纹识别的service开始 路径 f
  • python小游戏——跑酷小恐龙代码开源

    作者 小刘在这里 每天分享云计算网络运维课堂笔记 努力不一定有回报 但一定会有收获加油 一起努力 共赴美好人生 夕阳下 是最美的 绽放 愿所有的美好 再疫情结束后如约而至 目录 一 效果呈现 二 主代码 三 cfg 四 README 一 效
  • Python配置免费的OCR图片识别文字(附代码)

    今天刷帖刷到一个网站 可以免费OCR识别 但是具体的次数我没有计算 文档上也没有具体说明 那么我们一起来看看吧 首先网址在这里 点我直达 1 我们需要注册一个账号 获取非常重要的参数 ColaKey 2 接着我们看一下文档说明 可跳过 点我
  • 用Python实现队列(queue)

    一 队列的定义 队列 一种先进先出 FIFO First in First Out 的线性结构 即在队列的尾部入队 在队列的头部出队 入队 即队列添加成员 在队列的尾部完成 出队 即队列删除成员 在队列的头部完成 在创建队列时 一般以数组为
  • 登陆界面的测试

    一 功能 1 用户名和密码 用户名和密码的合法性 长度 字符 空 用户名和密码的一致性 验证码的合法性和一致性 2 登陆功能 跳转正确 3 页面其他链接 如忘记密码 4 记住用户名 记住密码的功能 5 输入框是否支持复制和粘贴 6 密码显示
  • 图像分割:Python的SLIC超像素分割

    图像分割 Python的SLIC超像素分割 1 什么是超像素 2 为什么超像素在计算机视觉方面有重要的作用 3 简单线性迭代聚类 SLIC 4 效果图 5 源码 参考 1 什么是超像素 在单个或多个通道中 图像表示为像素网格 我们采用这些M
  • mysql8 java Could not create connection to database server. Attempted reconnect 3 times问题

    最近照着网上的一个博主的例子 学习ssm 结果一个mysql8 搞得我都崩溃了 各种连不上 总结一下出错原因 1 maven中的jdbc连接jar包 版本也要换成高版本
  • Linux基本权限(详解)

    目录 文件权限位 更改文件权限 chmod指令 chown指令 chgrp指令 数字权限 umask命令 文件权限位 显示当前目录下文件的详细信息 ls l 也可以写成 ll Linux下文件的权限位共有十个 按照1333来划分 第一位代表
  • 服务器操作系统比较,服务器操作系统比较

    服务器操作系统比较 内容精选 换一换 Atlas 800 训练服务器 型号 9000 安装上架 服务器基础参数配置 安装操作系统等操作请参见 Atlas 800 训练服务器 用户指南 型号9000 风冷 或 Atlas 800 训练服务器
  • 特征筛选3——卡方检验筛选特征(单变量筛选)

    sklearn文档 https scikit learn org stable modules generated sklearn feature selection chi2 html 卡方检验只适用分类任务 用来检验特征与y是否相互独立
  • java获取response与request

    java获取response与request 方式一 监听 web xml
  • Makefile 多个目标匹配的问题

    在windows下直接使用mingw32 make ZTHREAD A the static link library file of ZThread ZTHREAD A F ZJ tools cpp libs ZThread 2 3 2
  • Flutter 文字渐变色

    目前在做的项目需要用到渐变文字的需求 但是都用图的话 会导致包很大 所以打算自己去写一个渐变 本次渐变用到的组件是ShaderMask这个组件来完成咱们的文字渐变色 代码实现 text里面的文字需要设置为白色字体 ShaderMask sh
  • [ 云计算 华为云 ] 解决办法:如何更换华为云云耀云服务器L实例的镜像

    文章目录 问题描述 分析原因 解决办法 文末送书 ANSYS Workbench项目分析与案例实操详解 博主推荐理由 本书内容简介 本书作者简介 废话在前 直接看解决办法的这段可以过 讲道理 一般情况下云服务器 镜像是随便更换的 但是我发现
  • 华为OD机试 - 查找众数及中位数(Java)

    题目描述 众数是指一组数据中出现次数量多的那个数 众数可以是多个 中位数是指把一组数据从小到大排列 最中间的那个数 如果这组数据的个数是奇数 那最中间那个就是中位数 如果这组数据的个数为偶数 那就把中间的两个数之和除以2 所得的结果就是中位
  • count(*)和group by的用法

    https www cnblogs com gongchengshiwhl p 7994761 html https blog csdn net weixin 44938368 article details 109614917 1 cou
  • 将设计稿图标制作成iconfont(ps cs6 + ai cs6)

    项目开发中需要用到icon iconfont网站上找的icon风格各式各样 就想着把设计稿的图标直接转成icon就好了 1 先在ps装一个脚本 save ps to svg1 0 jsx 放在ps安装目录下的 Presets Scripts
  • python Opencv和pyautogui实现自动识图点击

    python Opencv和pyautogui实现自动识图点击 1 导入python及其他模块 匹配类是上一章博客内容 pyautogui自带的图片匹配效果不是很理想 就使用Opencv的图片匹配来实现图片的定位 python 使用模版匹配
  • Vue.js 学习笔记十三:Vue Router 之导航守卫

    目录 导航守卫 全局前置守卫 全局后置钩子 路由独享的守卫 组件内的守卫 导航守卫 我们来考虑一个需求 在一个 SPA 应用中 如何改变网页的标题呢 网页标题是通过