在单个 Vue 导航中重定向两次

Ant*_*gos 10 vue.js vue-router

在我的 Vue 应用程序中,用户的主页取决于他们的角色。为了确保向用户显示正确的主页,我使用了这个导航守卫:

export default (to, from, next) => {
  const authService = getAuthService()

  if (to.path === '/') {
    // if they've requested the home page, send them to 
    // different pages depending on their role
    if (authService.isUser()) {
      next({ name: 'events' })

    } else if (authService.isAdmin()) {
      next({ name: 'admin-events' })

    } else {
      next()
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后当用户成功登录时,我将他们重定向到 '/'

  this.$router.push({path: '/'))
Run Code Online (Sandbox Code Playgroud)

上面的导航守卫将它们重定向到特定于角色的主页。但是,不允许在单个导航操作过程中重定向两次,并导致在第二次重定向发生时(在导航防护中)控制台中出现以下错误

未捕获(承诺)错误:通过导航守卫从"/login"到重定向"/"

我的应用程序中发生这种情况的另一种情况是 404 组件,它处理访问不存在的路由的尝试,即

  1. 用户尝试访问无效路由
  2. 404 组件重定向回 '/'
  3. 导航守卫重定向到用户特定的主页,导致错误

有没有一种方法可以支持这些用例而无需重定向两次?

Est*_*iaz 9

tldr:vm.$router.push(route)是一个承诺,需要.catch(e=>gotCaught(e))出错。


这将在下一个主要@4 中更改


目前@3 错误不区分它们是NavigationFailures还是regular Errors

之后的幼稚预期路线vm.$router.push(to)应该是to. 因此,一旦发生重定向,就可以期待一些失败消息。在将router.push修补为 promise 之前,错误被默默忽略。当前的解决方案是.catch(...)在每次推送时使用反模式 a ,或者预测设计中的更改并将其包装起来以暴露失败结果。

未来的计划是将这些信息放入结果中:

  let failure = await this.$router.push(to);
  if(failure.type == NavigationFailureType[type]){}
  else{}
Run Code Online (Sandbox Code Playgroud)

我这个错误只是设计使然,应该处理:

hook(route, current, (to: any) => { ... abort(createNavigationRedirectedError(current, route)) ...}
Run Code Online (Sandbox Code Playgroud)

所以基本上如果to包含一个重定向它是一个错误,这有点等于使用vm.$router.push到一个守卫。

要忽略未处理的错误行为,可以传递一个空的 onComplete(在未来版本中中断):

vm.$router.push(Route, ()=>{})
Run Code Online (Sandbox Code Playgroud)

或者把它包起来 try .. catch

try {

  await this.$router.push("/")
} catch {

}
Run Code Online (Sandbox Code Playgroud)

这可以防止承诺抛出未捕获


支持这一点而不重定向两次意味着你把守卫放在你的出口:

let path = "/"
navguard({path}, undefined, (to)=>this.$router.push(to||path))
Run Code Online (Sandbox Code Playgroud)

这将污染重定向到主页的每个组件


顺便说一句,该router-link组件使用了一个空的 onComplete


假设不允许重定向两次是错误的。