vue 全局前置守卫引起死循环的原因与解决方法

时间: 2020-01-04阅读: 1039标签: 循环

我们经常会用到全局前置守卫,如判断用户有没有登陆过,如果登陆过就直接跳到目的页面,如果没有登陆过,就跳转到登陆页。

先看官网对全局前置守卫的介绍

使用 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: true、name: 'home' 之类的选项以及任何用在router-link 的 to prop 或 router.push 中的选项。

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

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

回到我们刚才所说验证登陆使用全局前置守卫

router.beforeEach((to,from,next) =>{
  if (sessionStorage.getItem("token")) {
     if(to.path === "/login"){
       next({path:"/dashboard"})
     }
     else{
       alert("1")
       next()
     }     
  }else{
    next({path: "/login"})   // 会再次执行前置导航守卫,因为路径变化
  }
})

上面的代码表面看没有问题,

如果sessionStorage有token,并且如果即将要进入的目标路径是登陆页,就跳转到/dashboard页,如果是其它的页面,就进入

如果sessionStorage没有token 就进入登陆页

但是代码执行会引起死循环,原因是没有出口,执行next({path: "/login"})会再次执行全局前置导航守卫 

代码改成下面的就正常了

router.beforeEach((to, from, next) => {
  let token = window.sessionStorage.getItem('token');
  if (to.path != '/login' && !token) {
    next({
      path: '/login'
    })
  } else {
    if (to.path == '/login' && token) {
      next('/dashboard')
    } else {     
      next()
    }
  }
})

总结:执行next({ path: '/xxx' }) 跳到不同的地址都会再次执行 router.beforeEach 钩子函数

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

2.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/7392

关闭

for...of 循环在 JS 是不可或缺

请教大家一个问题:什么特性让该编程语言更加优秀?个人见解:当该特性可以组合多个其他语言特性时。JavaScript 中的for...of语句就是这种情况,可从ES2015开始使用。

为啥要放弃for循环?

创建一个新的数组,新的数组中的元素是通过检查指定数组中符合条件的元素;注意:1. filter()不会对空数组进行检测;2. filter()不会改变源是数组;

Js循环的几种方法

for 常用于循环数组 ,for in 常用来循环对象,不建议循环数组,因为i是字符串 可能会有隐患问题,for in 循环会找到 prototype 上去,所以最好在循环体内加一个判断

如何中断forEach循环

在使用for循环的时候可以使用break 或者return语句来结束for循环(return直接结束函数),但是如果使用forEach循环如何跳出循环呢?首先尝试一使用return语句----木有效果

forEach循环中你不知道的3件事

你觉得你真的学会用forEach了么?这是我之前对forEach循环的理解:就是一个普通语义化之后的for循环,可以被break,continue,return。这篇文章将向你展示forEach中你可能不了解的3件事。

js,jquery中.each()方法遍历循环如何终止方法

用.each()方法遍历节点的时候,用“return false”只能终止循环并继续执行循环之后的语句。代码如下:

javascript中怎么退出循环?

javascript中退出循环的方法:方法一、使用break语句退出循环。方法二、使用continue语句退出循环。方法三、使用return语句退出循环。break语句会使运行的程序立刻退出包含在最内层的循环或者退出一个switch语句。

node事件循环是什么?

node事件循环是Node.js处理非阻塞 I/O 操作的机制—尽管JavaScript是单线程处理的—当有可能的时候,它们会把操作转移到系统内核中去。Node.js 是单进程单线程应用程序,但是因为V8引擎提供的异步执行回调接口

关于for循环中使用setTimeout的四种解决方案

我们先来简单了解一下setTimeout延时器的运行机制。setTimeout会先将回调函数放到等待队列中,等待区域内其他主程序执行完毕后,按时间顺序先进先出执行回调函数。本质上是作用域的问题

JavaScript循环下的async/await

在进行业务开发的过程中,使用了数组的高级函数map,同时使用了ES6语法async/await,发现在map循环下任务是异步执行的,并不符合预期。Array的循环方法map、forEach、filter、reduce、some、every等是并行迭代,可以理解为async/await的效果是无效的

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!