在 beforeEach 中编辑路由失败,因为回调传入无效路由作为参数
Editing routes in beforeEach fails because callback passes in invalid routes as to and from parameters
我正在使用 Vue 开发移动前端。我想根据当前选项卡索引将路由转换动态更改为向左或向右滑动。
我在我的 App.js 中设置了一个转换组件,它根据这样的路线切换转换:
<transition :name="$route.meta.transition" mode="out-in">
所以,为了实现我想要的,我想我可以在每次路由更改时设置一个 beforeEach 钩子,然后修改当前的 route.meta.transition 和我的路由的 .meta.transition我正在导航到。
以下是路由定义:
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/routines',
name: 'routines',
component: () => import('../views/Routines/IndexView.vue'),
meta: { transition: 'slide-right', index: 0 }
},
{
path: '/routines/create',
name: '/routines/create',
component: () => import('../views/Routines/CreateView.vue'),
meta: { transition: 'zoom-in', index: 0 }
},
{
path: '/routines/:id',
name: '/routines/id',
component: () => import('../views/Routines/RoutineView.vue'),
meta: { transition: 'zoom-in', index: 0 }
},
{
path: '/log',
name: 'log',
component: () => import('../views/LogView.vue'),
meta: { transition: 'slide-right', index: 1 }
},
{
path: '/progress',
name: 'progress',
component: () => import('../views/ProgressView.vue'),
meta: { transition: 'slide-right', index: 2 }
},
{
path: '/settings',
name: 'settings',
component: () => import('../views/SettingsView.vue'),
meta: { transition: 'slide-right', index: 3 }
}
]
})
这是我正在设置的钩子,用适当的字符串替换 to
和 from
路由和修改后的路由:
router.beforeEach((to, from, next) => {
console.log(to, from)
if (to.meta.index < from.meta.index) {
console.log({...to, meta: {...to.meta, transition: 'slide-left'}})
router.addRoute({...to, meta: {...to.meta, transition: 'slide-left'}})
console.log({...from, meta: {...from.meta, transition: 'slide-left'}})
router.addRoute({...from, meta: {...from.meta, transition: 'slide-left'}})
}
next()
})
但是,to
和 from
参数似乎没有我之前定义的组件键,所以当我通过导航离开并用 addRoute
替换路由时然后返回,我收到此错误:Error: Invalid route component
确认 to
和 from
对象是无效路由:
如何解决这个问题以实现动态滑动行为?我认为这个钩子策略是有道理的。将来,我想添加更多逻辑,让我的子页面在父页面和子页面之间导航时放大和缩小。
谢谢!
您可以直接从路由器挂钩更新路由元数据,而不是使用 router.addRoute()
。 Vue Router docs 建议使用 afterEach()
挂钩:
// router.js
router.afterEach((to, from) => {
to.meta.transition = to.meta.index < from.meta.index ? 'slide-right' : 'slide-left'
})
我正在使用 Vue 开发移动前端。我想根据当前选项卡索引将路由转换动态更改为向左或向右滑动。
我在我的 App.js 中设置了一个转换组件,它根据这样的路线切换转换:
<transition :name="$route.meta.transition" mode="out-in">
所以,为了实现我想要的,我想我可以在每次路由更改时设置一个 beforeEach 钩子,然后修改当前的 route.meta.transition 和我的路由的 .meta.transition我正在导航到。
以下是路由定义:
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: '/routines',
name: 'routines',
component: () => import('../views/Routines/IndexView.vue'),
meta: { transition: 'slide-right', index: 0 }
},
{
path: '/routines/create',
name: '/routines/create',
component: () => import('../views/Routines/CreateView.vue'),
meta: { transition: 'zoom-in', index: 0 }
},
{
path: '/routines/:id',
name: '/routines/id',
component: () => import('../views/Routines/RoutineView.vue'),
meta: { transition: 'zoom-in', index: 0 }
},
{
path: '/log',
name: 'log',
component: () => import('../views/LogView.vue'),
meta: { transition: 'slide-right', index: 1 }
},
{
path: '/progress',
name: 'progress',
component: () => import('../views/ProgressView.vue'),
meta: { transition: 'slide-right', index: 2 }
},
{
path: '/settings',
name: 'settings',
component: () => import('../views/SettingsView.vue'),
meta: { transition: 'slide-right', index: 3 }
}
]
})
这是我正在设置的钩子,用适当的字符串替换 to
和 from
路由和修改后的路由:
router.beforeEach((to, from, next) => {
console.log(to, from)
if (to.meta.index < from.meta.index) {
console.log({...to, meta: {...to.meta, transition: 'slide-left'}})
router.addRoute({...to, meta: {...to.meta, transition: 'slide-left'}})
console.log({...from, meta: {...from.meta, transition: 'slide-left'}})
router.addRoute({...from, meta: {...from.meta, transition: 'slide-left'}})
}
next()
})
但是,to
和 from
参数似乎没有我之前定义的组件键,所以当我通过导航离开并用 addRoute
替换路由时然后返回,我收到此错误:Error: Invalid route component
确认 to
和 from
对象是无效路由:
如何解决这个问题以实现动态滑动行为?我认为这个钩子策略是有道理的。将来,我想添加更多逻辑,让我的子页面在父页面和子页面之间导航时放大和缩小。
谢谢!
您可以直接从路由器挂钩更新路由元数据,而不是使用 router.addRoute()
。 Vue Router docs 建议使用 afterEach()
挂钩:
// router.js
router.afterEach((to, from) => {
to.meta.transition = to.meta.index < from.meta.index ? 'slide-right' : 'slide-left'
})