【问题标题】:vue router next() function don't work in Promise in router.beforeEachvue router next() 函数在 router.beforeEach 中的 Promise 中不起作用
【发布时间】:2019-08-18 03:59:51
【问题描述】:

我有以下代码:

router.beforeEach((to, from, next) => {
  if (to.name !== from.name) {
    store
      .dispatch("fetchCurrentUser")
      .then(() => {
        console.log('then');
        // do something
        next();
      })
      .catch(() => {
        console.log('catch');
        router.push("/login");
        next();
    });
  } else {
    next();
  }
  // next();
});

我正在尝试获取当前用户,如果成功,则对这些数据进行处理,如果请求不成功,则将用户重定向到登录页面。但是 next () 调用不起作用,我在控制台中得到了“then”或“catch”,但是没有发生重定向,并且开始了无限循环。但是,如果我从条件(注释行)中获取 next (),则重定向工作正常。

【问题讨论】:

  • 您还有其他路线守卫吗?用beforeResolve 替换beforeEach 会改变什么吗?
  • @raina77ow,不,beforeResolve 的行为完全相同
  • 你能提供你的fetchCurrentUser的代码吗?我认为错误可能隐藏在这里。

标签: vue.js vue-router


【解决方案1】:

要重定向,您应该使用next('/')next({ path: '/' })

来自文档:

next: 函数:必须调用这个函数来解决钩子。这 action 取决于提供给 next 的参数:

next():移动到管道中的下一个钩子。如果没有钩子 左,导航被确认。

next(false):中止当前导航。如果浏览器 URL 是 更改(由用户手动或通过后退按钮),它将是 重置为 from 路由。

next('/') 或 next({ path: '/' }):重定向到不同的位置。 当前导航将中止,并开始新的导航。 您可以将任何位置对象传递给下一个,它允许您指定 选项,如 replace: true、name: 'home' 和使用的任何选项 router-link's to prop 或 router.push

【讨论】:

  • next("/login") 也没有调用
  • 再仔细看,我认为promise 是在错误的地方调用。这个例子展示了如何在进入路由之前获取数据:router.vuejs.org/guide/advanced/…
  • 很奇怪,如果我的项目中有超过200个组件,我将不得不在每个中注册一个处理程序
【解决方案2】:

promise 在函数结束后解析。

这意味着无论 promise 结果如何,被注释的next 都会发生。然后,promise 解决了,你调用另一个 next

底线是您不需要注释的 next 并且应该只覆盖承诺解决。

【讨论】:

  • 但我不想在承诺解决之前调用 next() 。我想获取用户数据并找出他的访问级别,以便了解将他进一步重定向到哪里
  • 我明白这一点。你打电话给旁边很多次。不需要最后一次调用。
【解决方案3】:

我能够在 beforeEach 中实现异步验证,在我的例子中是身份验证。

export async function onBeforeEach(to, from, next) {
  let { someUserToken } = to.query
  if (someUserToken) {
    let nextRoute = await authenticate(to)
    next(nextRoute)
  } else {
    const userToken = store.state.application.userToken
    if (!to.meta.public && !userToken) {
      next({ name: 'Forbidden' })    
    } else {
      next()
    }
  }
}

async function authenticate(to) {
  let { someUserToken, ...rest } = to.query

  return store
    .dispatch('application/authenticate', {
      someUserToken
    })
    .then(() => {
      return {
        name: 'Home',
        query: {
          ...rest
        }
      }
    })
    .catch(() => {
      return { name: 'Forbidden' }
    })
}

我希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2017-05-30
    • 2021-05-19
    • 1970-01-01
    • 2018-04-28
    • 2020-07-28
    • 2019-12-06
    • 2017-11-17
    • 2021-10-28
    • 1970-01-01
    相关资源
    最近更新 更多