vue-router default child route for tabs
Asked Answered
A

7

20

I'm trying to have a homepage with tabs containing 2 lists, with 1 open by default.

I have the following route config, I've changed the names to simplify

let routes = [{
    path: '/',
    name: 'home',
    component: require('./views/Home.vue'),
    children: [{
        path: 'list1',
        name: 'home.list1',
        component: require('./views/List1.vue')
    }, {
        path: 'list2',
        name: 'home.list2',
        component: require('./views/List2.vue')
    }]
}

Inside ./views/Home.vue I have a <router-view></router-view> below 2 <router-link>s for each tab (child route).

When I visit the app route http://domain/ I would like to activate the list1 tab. The only way I can currently do this is if I visit http://domain/list1.

I have tried

children: [{
    path: '',
    name: 'home.list1'

and this initially works well, however if I visit http://domain/list2 both my tab links (router-links) have the active state.

JSFiddle which I can't get to run but helps for context

Is there a better solution to this?

Asterism answered 23/2, 2017 at 22:4 Comment(5)
router.vuejs.org/en/essentials/nested-routes.html see example on very bottom of the page.Illative
@Illative but when you define a second child route, when it's active both child <router-link> will be activeAsterism
It's hard to tell without example. But you can try exact prop on router link router.vuejs.org/en/api/router-link.htmlIllative
Example added to OPAsterism
@Illative exact worked thank you! Want to post it as an answer so I can mark as answered?Asterism
E
19

Add one more child route with redirect (should be first)

  children: [{
    path: '',
    redirect: 'list1', // default child path
  },
  ...
  ]
Egeria answered 28/2, 2019 at 19:19 Comment(1)
This works but with redirect: { name: 'home.list1' }. You need to name the default path and use it as the argument to redirect.Krystalkrystalle
I
11

For making a component(tab) appear default at visiting the parent route, you need to add a path as '' (empty string)

The following is a n example from the Vue Router docs

const router = new VueRouter({
  routes: [
    {
      path: '/user/:id', component: User,
      children: [
        // UserHome will be rendered inside User's <router-view>
        // when /user/:id is matched
        { path: '', component: UserHome },

        // ...other sub routes
      ]
    }
  ]
})

Don't use a '/', it will be considered as the root route.

Implicatory answered 17/9, 2017 at 6:44 Comment(0)
S
8

You need to put the redirect on the parent, and it works on the first load. Otherwise, it only works when I reload the page.

  • put redirect: 'home.list1' on the parent
  • put your child as path: ''

hope it works.

let routes = [{
        path: '/',
        name: 'home',
        redirect: {name: 'home.list1'}, // Redirect to named route
        // redirect '/list2' // Or redirect to path
        component: require('./views/Home.vue'),
        children: [{
            path: '',
            name: 'home.list1',
            component: require('./views/List1.vue')
        }, {
            path: 'list2',
            name: 'home.list2',
            component: require('./views/List2.vue')
        }]
    }
Starter answered 16/12, 2020 at 17:46 Comment(0)
P
2

Here is what works.

You have to use redirect: {name: 'home.list1'} (for the named route) property on your parent route 'home'.

Make sure you use the correct redirect property format either for named route (as above) or for path: redirect: '/list1'.

Here is the correct routes config which is only 1 line (the redirect one) different vs your config:

const routes = [{
        path: '/',
        name: 'home',
        redirect: 'home.list1',
        component: require('./views/Home.vue'),
        children: [{
            path: 'list1',
            name: 'home.list1',
            component: require('./views/List1.vue')
        }, {
            path: 'list2',
            name: 'home.list2',
            component: require('./views/List2.vue')
        }]
    }

Then every visit to / (your 'home' route) would be redirected to /list1.

Moreover, the router-link-active and router-link-exact-active will be correctly assigned on child link (both of them) and on parent link (only router-link-active).

This will also work for deeper nested non-child and child routes.

For more redirect & aliasig options see the official docs.

Pr answered 24/12, 2020 at 12:49 Comment(0)
C
1

I think what you want to do works if your home route isn't "/"

routes: [
    { path: '/home', 
        name: 'home',
        component: require('./views/home.vue')
        children: [
            { path: '/', name: 'list1', component: list1 },
            { path: 'list2', name: 'list2', component: list2},
        ],
    }
]

This will load the home component and the list1 component inside of your initial . Then you can user router link to nav to list2:

<router-link :to="{ name: 'list2', params: { ...}}">

Or, maybe I don't understand the question.

Clarence answered 23/2, 2017 at 23:23 Comment(1)
I can't get the fiddle to run but here it is for context: jsfiddle.net/wtpuevc6/33Asterism
M
1

This is the best way I've found to do it, preserving the route parameters:

{
  path: "/users/:id(\\d+)",
  component: Users,
  children: [
    {
      path: '',
      redirect: { name: "ChildOne" },
    },
    {
      path: "child-one",
      name: "ChildOne",
      component: ChildOne,
    },
    {
      path: "child-two",
      component: ChildTwo,
    },
    {
      path: "child-three",
      component: ChildThree,
    },
  ],
},

For example, when navigating to /users/1, the route is redirected to /users/1/child-one. I found that when I do it with a path, the id is not treated as a route param and is instead treated as text (so would try to redirect to /users/:id/child-one instead)

Monarda answered 19/7, 2023 at 8:52 Comment(0)
K
0

This is inspired by @NaN's answer. You need to name the default route apart from adding an empty route and redirecting from it.

  {
    path: '/user-layout/:user',
    component: () => import('../layouts/UserLayout.vue'),
    children: [
      //add an empty route and redirect to 'profile'
      {
        path: '',
        redirect: { name: 'profile' }, // path doesn't work.
      },
      {
        path: 'profile',
        name: 'profile', //name your default route
        component: () => import('../pages/ProfilePage.vue'),
      },
      {
        path: 'posts',
        component: () => import('../pages/PostsPage.vue'),
      },
    ]
  },

/user-layout/johny will show /user-layout/johny/profile

In the UserLayout component you can have

<RouterLink to="profile">Profile</RouterLink>
<RouterLink to="posts">Posts</RouterLink>

to move between pages.

Krystalkrystalle answered 3/5 at 1:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.