Allows the routes to be defined with a prefix that doesn't need to be repeated in each route.
Currently this doesn't work because the parent route doesn't have a component specified. This feature isn't about nested routes but just about nested paths.
{ path: '/prefix': children: [
{ path: 'one', component: ... },
{ path: 'two', component: ... },
]}
Creates /prefix/one and /prefix/two.
If you need nested path the recommended approach is to use a function to generate the routes with the prefix:
function prefixRoutes(prefix, routes) {
return routes.map(route => route.path = prefix + '/' + route.path)
}
new Router({
routes: [
// some routes
...prefixRoutes('/prefix', [
{ path: 'one', component: ... },
{ path: 'two', component: ... },
])
]
})
I hacked around this with a component named PassThrough that just contains a <router-view />. It should be possible to make this the default behavior when the component property is omitted from a route.
<!-- PassThrough.vue -->
<template>
<router-view />
</template>
// router.js
new Router({routes: [{
path: '/prefix',
component: PassThrough,
children: [
{ path: 'one', component: ... },
{ path: 'two', component: ... },
]
}]})
If you need nested path the recommended approach is to use a function to generate the routes with the prefix:
function prefixRoutes(prefix, routes) { return routes.map(route => route.path = prefix + '/' + route.path) } new Router({ routes: [ // some routes ...prefixRoutes('/prefix', [ { path: 'one', component: ... }, { path: 'two', component: ... }, ]) ] })
How should specify path to direct? Just specifying without prefix or with both is taking me to 404.
If you need nested path the recommended approach is to use a function to generate the routes with the prefix:
function prefixRoutes(prefix, routes) { return routes.map(route => route.path = prefix + '/' + route.path) } new Router({ routes: [ // some routes ...prefixRoutes('/prefix', [ { path: 'one', component: ... }, { path: 'two', component: ... }, ]) ] })
This throw a error because inside the map you return only the path.
The solution is:
function prefixRoutes(prefix, routes) {
return routes.map((route) => {
route.path = prefix + '' + route.path;
return route;
});
}
Example:
...prefixRoutes('/shop/:shopId', [
{
path: '/',
name: 'Shop',
component: () => import('../views/shop/Shop.vue'),
},
{
path: '/category/:categoryId',
name: 'Shop Products',
component: () => import('../views/shop/Shop.vue'),
},
]),
Routes return:
4: {path: "/shop/:shopId/", name: "Shop", component: 茠}
5: {path: "/shop/:shopId/category/:categoryId", name: "Shop Products", component: 茠}
You can change the union with prefix inside the function ("") to ("/") if you not start the children paths with "/"
Expanding on what @deckar01 proposed, we can do away with the redundant SFC 馃憞
new Router({routes: [{
path: '/prefix',
component: {
// Inline declaration of a component that renders our <router-view>
render: (c) => c('router-view'),
},
children: [
{ path: 'one', component: ... },
{ path: 'two', component: ... },
]
}]})
Just hit this issue again. I keep on forgetting this one on new projects where it makes sense to "namespace" several pages... and then I wonder why things broke, as there's just a blank page without error messages.
Then I re-read the docs, and read the thing with two <router-view></router-view> in https://router.vuejs.org/guide/essentials/nested-routes.html, and search for like "vue nested routes without main component", find this issue, and remember that I have to use the solution above.
It makes little sense to me that the child is not inserted into the main <router-view></router-view> when the parent has no component.
Also - hello, future me :wave:
I'd also like to give this issue a "bump".
Nested routes are particularly helpful for displaying a breadcrumb in my UI. Though the routes are nested, there's no point nesting components.
For example, in my app the path /leagues/:leagueId should render a completely different page than /leagues/:leagueId/teams/:teamId. At most, these pages share a top level component that serves as a base template. But the :teamId page should not inherit anything from the :leagueId page. They show completely different information and operate independently of each other. Currently I use the "pass through" option explained above, but creating a "dummy" component just to get the app to render correctly feels hacky.
It would be cleaner and less cumbersome if we didn't have to add a component to every route, and a child route was rendered in the component of it's closest ancestor with router-view.
Expanding on what @deckar01 proposed, we can do away with the redundant SFC 馃憞
new Router({routes: [{ path: '/prefix', component: { // Inline declaration of a component that renders our <router-view> render: (c) => c('router-view'), }, children: [ { path: 'one', component: ... }, { path: 'two', component: ... }, ] }]})
hi, @andreasvirkus. Do you know how to use it in next router of vue 3 ?
it will be throw TypeError with render: (c) => c('router-view')

log the 'c' out as follow:

I think you'd need to use Vue.h (docs: https://v3.vuejs.org/guide/render-function.html#render-functions)
import { h } from 'vue'
// or
// import Vue from 'vue' // and use it as `Vue.h`
// router setup...
render: () => h('router-view'),
I haven't tested this through yet though.
@andreasvirkus Thank you, It's all right!
Most helpful comment
I hacked around this with a component named
PassThroughthat just contains a<router-view />. It should be possible to make this the default behavior when thecomponentproperty is omitted from a route.