Vue router taking me to parent route mistakenly

Viewed 1400

My Vue router normally works just fine, but when I'm on certain routes and want to navigate to one of the parent routes it instead takes me back to the root redirected route instead of the child route I want it to go to

For example, the route in question is account-creation. When I navigate there with $router.push('/account-creation') from most routes it works just fine. However, if I navigate there from any of the account details children routes (like overview), it instead takes me to /account and not /account-creation!

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    component: () => import('MainLayout.vue'),
    children: [
      { path: '/', redirect: '/account' },
      { path: 'account', component: () => import('AccountList.vue') },
      { path: 'account-creation', component: () => import('AccountCreation.vue') },
      { 
        path: 'account/:accountId', 
        component: () => import('AccountDetailsLayout.vue'),
        children: [
          { path: 'overview', component: () => import('AccountOverview.vue') },
          { path: 'settings', component: () => import('AccountSettings.vue') },
        ],
      }
    ]
  }
];

I have tried every manner of solution I could find online, including using fully qualified paths, re-ordering routes, using names routes, all to no avail

I'm pretty sure it's related to the redirect to /account in the root / path, but can't figure out how to maintain that functionality and fix the behavior

How can I ensure navigating to account-creation from account/{id}/overview correctly navigates to account-creation, instead of the redirect route at /account 

Things I've tried

  • using named paths
  • using path: object to route to
  • re-ordering routes
  • full paths in routes such as /account/:accountId/overview
2 Answers

It seems there are conflicts on your root routes (every path with "/" in front). You could check the vue-router documentation for nested routes Vue Nested Routes


const routes: RouteRecordRaw[] = [
    {
        path: '/',
        component: () => import('AccountList.vue'),
        alias: '/account'
    },
    {
        path: '/account-creation',
        component: () => import('AccountCreation.vue')
    },
    {
        path: '/account/:accountId',
        component: () => import('AccountDetailsLayout.vue'),
        children: [
            {
                path: 'overview',
                component: () => import('AccountOverview.vue')
            },
            {
                path: 'settings',
                component: () => import('AccountSettings.vue')
            }

    }
]

Something like this could work, but as you pointed out the redirect on "/" is a code smell since you load different components.
The MainLayout component will never be mounted with this code, instead you will be redirected to AccountList.

EDIT

I edited the original answer based on Excalibaard's comment. You probably should add <router-view> in your MainLayout.vue

P.S. /account path should be accounts as it renders a list

If you are passing id to the route correctly, then the issue would be that You have to have a child router-view tag in your AccountDetailsLayout.vue in order to display this route with url account/{id}/overview . Since this is the grandchild of the main layout.Just put the router-view tag in your file like this.

AccountDetailsLayout.vue
-----------------------

<template>
------
 <router-view></router-view>
 -----
</template>

<script>

export default {
    name: "AccountDetailsLayout",
    components: {},
    store,
    data() {
        return {};
    },
    computed: {},
    mounted() {},
    methods: {}
};
</script>

<style scoped></style>

Related