详解vue-router导航守卫


Posted in Javascript onJanuary 19, 2019

当做Vue-cli项目的时候需要在路由跳转前做一些验证,比如登录验证,是网站中的普遍需求。

对此,vue-router 提供的 beforeEach可以方便地实现全局导航守卫(navigation-guards)。组件内部的导航守卫函数使用相同,只是函数名称不同(beforeRouteEnter 、beforeRouteUpdate(2.2 新增) 、beforeRouteLeave)。

钩子(Hook),早期编程可能有个概念叫句柄,不知道将两者类比而且强行归为一类是不是合适。钩子的用处是在某个特定流程中的不同时机暴露出一些函数,使得用户可以通过覆写这些函数实现在原有位置执行自己的代码逻辑的功能。

1. 分类

vue-router中的导航钩子按定义位置不同(执行时机也不同)分为全局钩子、路由级钩子和组件级钩子。

  • 全局钩子

全局钩子有三个,分别是beforeEach、beforeResolve和afterEach,在路由实例对象注册使用;

  • 路由级钩子

路由级钩子有beforeEnter,在路由配置项中项定义;

  • 组件级钩子

组件级钩子有beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave,在组件属性中定义;

官方文档地址:https://router.vuejs.org/zh-cn/advanced/navigation-guards.html

如何设置一个全局守卫

你可以使用 router.beforeEach 注册一个全局前置守卫:就是在你router配置的下方注册

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: true、name: 'home' 之类的选项以及任何用在 router-link 的 to prop 或 router.push 中的选项。
  • next(error): (2.4.0+) 如果传入 next 的参数是一个 Error 实例,则导航会被终止且该错误会被传递给 router.onError() 注册过的回调。

确保要调用 next 方法,否则钩子就不会被 resolved。

一、认识beforeEach()中的参数

详解vue-router导航守卫

详解vue-router导航守卫

全局守卫(就是对整个路由实例进行守卫,对其中的子路由也会进行守卫)

详解vue-router导航守卫

路由独享的守卫(对实例中某个路由进行守卫)

详解vue-router导航守卫

小结:

全局和局部

import Vue from 'vue';
import VueRouter from 'vue-router';
// Vue中插件必须use注册
Vue.use(VueRouter);
// 路由配置项,此处是路由级钩子的定义
const routes = [{
    path: '/',
    component: resolve => require(['./index.vue'], resolve),
    keepAlive: true,
  },
  {
    path: '/user/:userName',
    keepAlive: true,
    beforeEnter(to,from,next){
      console.log('router beforeEnter');
      next();
    },
    component: resolve => require(['./user.vue'], resolve),
  }];
// 实例化路由对象
const router = new VueRouter({
  routes
});
// 全局钩子
router.beforeEach((to,from,next)=>{
  console.log('global beforeEach')
  next();
});
router.beforeResolve((to,from,next)=>{
  console.log('global beforeResolve')
  next();
});
router.afterEach((to,from,next)=>{
  console.log('global afterEach')
});
// 实例化Vue对象并挂载
new Vue({
  router
}).$mount('#app');

use.vue组件中使用导航守卫

<template>
  <div>
    <h1>{{ msg }}</h1>
    <p>我是:{{userName}}</p>
  </div>
</template>
<script>
  export default {
    name: 'user',
    data () {
      return {
        msg: '这里是 User Page.',
        userName: '叶落'
      };
    },
    methods: {},
    mounted () {
      var me = this;
      me.userName = me.$route.params.userName;
      console.log('user mounted.');
    },
    beforeRouteEnter (to, from, next) {
      console.log('component beforeRouteEnter');
      next();
    },
    beforeRouteUpdate (to, from, next) {
      console.log('component beforeRouteUpdate');
      next();
    },
    beforeRouteLeave(to,from,next){
      console.log('component beforeRouteLeave');
      next();
    }
  };
</script>

执行时机

由首页进入user页面:

global beforeEach > router beforeEnter > component beforeRouteEnter > global beforeResolve > global afterEach > mounted

由user回到首页:

component beforeRouteLeave => global beforeEach => global beforeResolve => global afterEach

排除beforeRouteUpdate,其余六个导航钩子的执行时机其实很好理解。大体按照leave、before、enter、resolve、after的顺序并全局优先的思路执行。beforeRouteUpdate的触发是在动态路由情形下,比如 path: '/user/:userName' 这条路由,当页面不变更只动态的改变参数userName时,beforeRouteUpdate便会触发。

详解vue-router导航守卫

结论:使用vue组件拼凑成整个应用,每个页面是独立的,路由依靠链接跳转,会刷新页面。使用vue-router则可以不刷新页面加载对应组件,hash和history模式模拟路径变化,不刷新页面。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。如果你想了解更多相关内容请查看下面相关链接

Javascript 相关文章推荐
JScript中使用ADODB.Stream判断文件编码的代码
Jun 09 Javascript
js中获取事件对象的方法小结
Mar 13 Javascript
解析Javascript中中括号“[]”的多义性
Dec 03 Javascript
jquery让返回的内容显示在特定div里(代码少而精悍)
Jun 23 Javascript
weUI应用之JS常用信息提示弹层的封装
Nov 21 Javascript
angular4中关于表单的校验示例
Oct 16 Javascript
解决Vue 浏览器后退无法触发beforeRouteLeave的问题
Dec 24 Javascript
JS实现常见的查找、排序、去重算法示例
May 21 Javascript
详解vue开发中调用微信jssdk的问题
Apr 16 Javascript
redux.js详解及基本使用
May 24 Javascript
layui复选框的全选与取消实现方法
Sep 02 Javascript
vue-resourc发起异步请求的方法
Feb 11 Javascript
JS尾递归的实现方法及代码优化技巧
Jan 19 #Javascript
javascriptvoid(0)含义以及与&quot;#&quot;的区别讲解
Jan 19 #Javascript
js实现延迟加载的几种方法详解
Jan 19 #Javascript
15分钟深入了解JS继承分类、原理与用法
Jan 19 #Javascript
js嵌套的数组扁平化:将多维数组变成一维数组以及push()与concat()区别的讲解
Jan 19 #Javascript
js的各种数据类型判断的介绍
Jan 19 #Javascript
JavaScript实现与使用发布/订阅模式详解
Jan 19 #Javascript
You might like
PHP语法速查表
2006/12/06 PHP
PHP mkdir()无写权限的问题解决方法
2014/06/19 PHP
浅谈php(codeigniter)安全性注意事项
2017/04/06 PHP
浅谈Yii乐观锁的使用及原理
2017/07/25 PHP
asp.net下利用js实现返回上一页的实现方法小集
2009/11/24 Javascript
Javascript UrlDecode函数代码
2010/01/09 Javascript
jQuery实现点击小图显示大图代码分享
2015/08/25 Javascript
jQuery zclip插件实现跨浏览器复制功能
2015/11/02 Javascript
详解jQuery移动页面开发中的ui-grid网格布局使用
2015/12/03 Javascript
js实现上传文件添加和删除文件选择框
2016/10/24 Javascript
微信小程序 UI布局常用技巧整理总结
2016/12/05 Javascript
EasyUI中的dataGrid的行内编辑
2017/06/22 Javascript
bootstrap fileinput插件实现预览上传照片功能
2018/01/23 Javascript
浅析从vue源码看观察者模式
2018/01/29 Javascript
JavaScript遍历数组的三种方法map、forEach与filter实例详解
2019/02/27 Javascript
vue路由--网站导航功能详解
2019/03/29 Javascript
JS实现的简单tab切换功能完整示例
2019/06/20 Javascript
详解使用mocha对webpack打包的项目进行&quot;冒烟测试&quot;的大致流程
2020/04/27 Javascript
Vue使用Proxy代理后仍无法生效的解决
2020/11/13 Javascript
[02:17]TI4西雅图DOTA2前线报道 啸天mik夫妻档解说
2014/07/08 DOTA
Python中的字符串类型基本知识学习教程
2016/02/04 Python
python矩阵/字典实现最短路径算法
2019/01/17 Python
Python爬取数据保存为Json格式的代码示例
2019/04/09 Python
详解如何从TensorFlow的mnist数据集导出手写体数字图片
2019/08/05 Python
Python爬取智联招聘数据分析师岗位相关信息的方法
2019/08/13 Python
Python 取numpy数组的某几行某几列方法
2019/10/24 Python
6行Python代码实现进度条效果(Progress、tqdm、alive-progress​​​​​​​和PySimpleGUI库)
2020/01/06 Python
Stuart Weitzman欧盟:美国奢华鞋履品牌
2017/05/24 全球购物
Boden美国官网:英伦原创时装品牌
2017/07/03 全球购物
澳大利亚婴儿礼品公司:The Baby Gift Company
2018/11/04 全球购物
Zooplus罗马尼亚:宠物食品和配件
2019/11/02 全球购物
西班牙鞋子和箱包在线销售网站:zapatos.es
2020/02/17 全球购物
2015年幼儿园班主任工作总结
2015/05/12 职场文书
班主任远程培训研修日志
2015/11/13 职场文书
python实现Thrift服务端的方法
2021/04/20 Python
CSS 鼠标点击拖拽效果的实现代码
2022/12/24 HTML / CSS