摘要

允许导航守卫返回其值或其 Promise,而不是调用 next

  1. // change
  2. router.beforeEach((to, from, next) => {
  3. if (!isAuthenticated) next(false)
  4. else next()
  5. })
  6. // into
  7. router.beforeEach(() => isAuthenticated)

由于我们可以检测导航守卫的数量或参数,我们可以自动知道是否应该查看返回值。这不是一个破坏性的变化。

基本范例

N/A

动机

  • 避免忘记调用 next
  • 避免多次调用 next 的问题(因为我们只能返回一次)
  • return 更常用,因为它只能被调用一次
  • 如果它们都不被使用的话,则避免了在函数中需要 3 个参数。

具体设计

如果 2 个参数被传递给一个导航守卫,Vue Router 会把返回的值看成是传递给 next 一样。

校验/取消导航

为了校验一个导航,目前你必须调用 next()next(true)。相反,你可以不返回任何东西(与明确返回 undefined)或返回 true。要取消导航,你可以调用 next(false),现在你可以明确的返回 false

  1. router.beforeEach((to) => {
  2. if (to.meta.requiresAuth && !isAuthenticated) return false
  3. })
  4. // with async / await
  5. router.beforeEach(async (to) => {
  6. return await canAccessPage(to)
  7. })

重定向到不同的位置

我们可以通过返回给 router.push 的同类型对象来重定向到一个位置:

  1. router.beforeEach((to) => {
  2. if (to.meta.requiresAuth && !isAuthenticated)
  3. return {
  4. name: 'Login',
  5. query: {
  6. redirectTo: to.fullPath,
  7. },
  8. }
  9. })
  10. // with async / await
  11. router.beforeEach(async (to) => {
  12. if (!(await canAccessPage(to))) {
  13. return {
  14. name: 'Login',
  15. query: {
  16. redirectTo: to.fullPath,
  17. },
  18. }
  19. }
  20. })

错误

仍然可以通过同步或者抛出抛出意外的错误:

  1. router.beforeEach((to) => {
  2. throw new Error()
  3. })
  4. // with async / await
  5. router.beforeEach(async (to) => {
  6. throw new Error()
  7. })
  8. // with promises
  9. router.beforeEach((to) => {
  10. return Promise.reject(new Error())
  11. })

缺点

  • Vue Router 3 可能预设了更高的实现成本

备选方案

  • 这可以用一个辅助函数来实现,但这个想法是要改变我们编写导航守卫的方式。

采纳策略

没有解决的问题

N/A