- 开始时间:2020-06-08
- 目标主要版本:Vue Router 3 and 4
- 引用 issue:https://github.com/vuejs/rfcs/issues/177
- 实现的 PR:https://github.com/vuejs/vue-router-next/pull/343
摘要
允许导航守卫返回其值或其 Promise,而不是调用 next:
// changerouter.beforeEach((to, from, next) => {if (!isAuthenticated) next(false)else next()})// intorouter.beforeEach(() => isAuthenticated)
由于我们可以检测导航守卫的数量或参数,我们可以自动知道是否应该查看返回值。这不是一个破坏性的变化。
基本范例
N/A
动机
- 避免忘记调用
next - 避免多次调用
next的问题(因为我们只能返回一次) - return 更常用,因为它只能被调用一次
- 如果它们都不被使用的话,则避免了在函数中需要 3 个参数。
具体设计
如果 2 个参数被传递给一个导航守卫,Vue Router 会把返回的值看成是传递给 next 一样。
校验/取消导航
为了校验一个导航,目前你必须调用 next() 或 next(true)。相反,你可以不返回任何东西(与明确返回 undefined)或返回 true。要取消导航,你可以调用 next(false),现在你可以明确的返回 false。
router.beforeEach((to) => {if (to.meta.requiresAuth && !isAuthenticated) return false})// with async / awaitrouter.beforeEach(async (to) => {return await canAccessPage(to)})
重定向到不同的位置
我们可以通过返回给 router.push 的同类型对象来重定向到一个位置:
router.beforeEach((to) => {if (to.meta.requiresAuth && !isAuthenticated)return {name: 'Login',query: {redirectTo: to.fullPath,},}})// with async / awaitrouter.beforeEach(async (to) => {if (!(await canAccessPage(to))) {return {name: 'Login',query: {redirectTo: to.fullPath,},}}})
错误
仍然可以通过同步或者抛出抛出意外的错误:
router.beforeEach((to) => {throw new Error()})// with async / awaitrouter.beforeEach(async (to) => {throw new Error()})// with promisesrouter.beforeEach((to) => {return Promise.reject(new Error())})
缺点
- Vue Router 3 可能预设了更高的实现成本
备选方案
- 这可以用一个辅助函数来实现,但这个想法是要改变我们编写导航守卫的方式。
采纳策略
- 在 Vue Router 4 中添加两种语法(https://github.com/vuejs/vue-router-next/pull/343/files)
- 尽管这不是一个破坏性的变化,但一个 codemod 应该能够处理这个转换。
没有解决的问题
N/A
