Lets say i have a simple CRUD UI with a listing and a details view.
The route config would look something like this:
{
path: '/users',
name: 'Users',
components: {
navigation: Navigation,
toolbar: Toolbar,
},
children: [
{
path: '',
name: 'UserList',
components: {
default: UserList,
},
},
{
path: ':userId',
name: 'UserDetails',
components: {
default: UserDetails,
},
},
],
}
Also my App.vue template would look similar to this:
div
.toolbar
router-view(name="toolbar")
.navigation
router-view(name="navigation")
.content
router-view
This does not work as expected because the child routes can only target views inside either parents currently rendered views.
The first i tried was to just drop in a view into the parents default view:
{
name: 'Users',
components: {
navigation: Navigation,
toolbar: Toolbar,
default: Vue.component('router-view')
},
},
But this leads to infinite recursion with maximum stack size error.
The next thing i tried was flattening the routes and it worked, but is much more verbose to configure.
Basically the route nesting must follow your component structure insteadof a more "natural" approach like navigation structure (where is the visitor?), the url structure (whats the name of the currently visited location?) or config structure (which routes share commen settings?). The URL structure can already be freely set, because you can use absolute paths in nested routes. But its a hassle to structure the route config to follow navigation structure without implying a specific component structure.
A new config option could be provided to switch the view targeting behavior. This will maintain BC and allows more versatility when structuring the route config
Keep in mind combining named routes with nested views is quite complex architecture, check https://router.vuejs.org/guide/essentials/named-views.html#nested-named-views for more info
Unfortunately, I don't find this clear enough as a feature request...
I checked the guide. I know how it works. The problem i describe is that a second level nested route can only target views (named or not) that have exactly one route-view in the component ancestor chain. This forces your route config structure to match exactly your component structure or vice versa.
Unfortunately, I don't find this clear enough as a feature request...
What can i do to clarify the request?
This forces your route config structure to match exactly your component structure
Yeah, that's the point for a page component
If you take the OP example, the route config reflects the navigation concept: Listing page -> Details page. But the component structure is different. There is no concept of nesting in this particular layout. The details page should get rendered into the same base layout as the listing page. But without introducing an intermediate component providing nothing else but a second level route-view, you simple can not facilitate route nesting (and therefore break away from making your route config reflect your navigation concept).
Even if I use an intermediate noop component providing a 2nd level router-view for the content area, there are cases that are extremly cumbersome to make work, like replacing the default toolbar (defined in the parent route) with a specialized one in just one of the nested routes:
{
path: '/users',
name: 'Users',
components: {
navigation: Navigation,
toolbar: Toolbar,
},
children: [
{
path: '',
name: 'UserList',
components: {
default: UserList,
},
},
{
path: ':userId',
name: 'UserDetails',
components: {
toolbar: SpecialUserDetailsToolbar, // this doesnt work at all
default: UserDetails,
},
},
],
}
An alternative algorithm for selecting the component of a view that makes nested routes much more versatile would be something like that:
function getComponentForView(viewName, currentRoute) {
do {
if (currentRoute.components[viewName]) {
return currentRoute.components[viewName];
}
} while(currentRoute = currentRoute.$parent);
}
This is a pretty naive implementation though which would require app-wide uniquely named router-views. (Though this limitation isnt that far away from the current requirement of having uniquely named router-views per nesting level, which imho is much harder to wrap your head around.)
@backbone87 Did you find a satisfactory way of implementing this in the current version of Vue 2.x? I currently have a similar need where I have an Account details view with a nested router-view for some content, but I also have other details views that only make sense in the context of a given account, but doesn't want to reuse the Account details component. These other details views have routes of the form /account/:accountId/otherthing/:otherthingid that would make sense as child routes of the /account/:accountId route, but I cannot find a way to do this while replacing the entire view.
Maybe someone needs example like this:
https://jsfiddle.net/grouch/u8fxokya/
Although, you can't access parent named router-views while child navigating, you can prepare a custom behaviour using route's meta and
I achieved it using the component tag.
In my Layout component I added that:
<component v-if="$route.meta.modal" :is="$route.meta.modal"></component>
Now in my route config I just have to use meta:
{
name: 'Services',
path: '/services',
component: () => import(/* webpackChunkName: 'services' */ '@/pages/Services/Services.vue'),
meta: {
private: true
},
children: [
{
name: 'NewService',
path: 'new',
component: {},
meta: {
modal: () => import(/* webpackChunkName: 'services' */ '@/pages/Services/New.vue')
}
}
]
}
Instead of using Vue.component('router-view') directly, you can make a pass through component that just contains a router-view and it can be reused as needed.
https://github.com/vuejs/vue-router/issues/2105#issuecomment-524409039
Most helpful comment
I achieved it using the
componenttag.In my Layout component I added that:
Now in my route config I just have to use meta: