Home > database >  Editing routes in beforeEach fails because callback passes in invalid routes as to and from paramete
Editing routes in beforeEach fails because callback passes in invalid routes as to and from paramete

Time:05-30

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:

enter image description here

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'
})

demo

  • Related