I'm working on a mobile frontend with Vue. I'd like to dynamically change route transitions to slide left or right depending on the current tab index.
I set up a transition component in my App.js which switches the transition based off the route like this:
<transition :name="$route.meta.transition" mode="out-in">
So, to achieve what I want, I thought I could set up a beforeEach hook on each route change, and then modify the current route.meta.transition, and the .meta.transition of the route I'm navigating to.
Here are the route definitions:
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 }
}
]
})
And this is the hook I'm setting up to replace the to
and from
routes with modified routes with the appropriate string:
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()
})
However, it appears that the to
and from
parameters don't have the component keys I defined earlier, so when I replace the routes with addRoute
by navigating away and then navigate back, I get this error: Error: Invalid route component
Confirmation that the to
and from
objects are invalid routes:
How can I achieve solve this issue to achieve this dynamic sliding behavior? I think this hook strategy makes sense. In the future, I'd like to add some more logic to let my child pages zoom in and out when you navigate between a parent and child page.
Thanks!
CodePudding user response:
Instead of using router.addRoute()
, you can update the route meta directly from the router hook. The Vue Router docs suggest using the afterEach()
hook:
// router.js
router.afterEach((to, from) => {
to.meta.transition = to.meta.index < from.meta.index ? 'slide-right' : 'slide-left'
})