I’m not sure whether I understand you correctly.
You ask where the difference is between having these nested routes and the approach to not having nested routes and having all of them at the top level of the configuration?
If so, nested routes allow you to reuse code and logic. Imagine a detail view of a product in a store. You have a route to view the single product and edit it. With nested route you can reuse the code required for fetching the product or adding an access control.
In the original vue app, I presume that you have a file App.vue, which essentially serves as the EmptyRouterView for all of your other views, right? Without nesting routes, you could have separate routes like products/:id/details and products/:id/edit, etc. The solution described in the article seems to recreate this structure. If the parent is truly empty (my App.vue actually contains my navigation and notification components) and the others are at the same level, I don't see how you can reuse code any more than I reuse code from App.vue. What am I missing? For example, I am creating a structure that has Projects and Documents s.t. :doc belongs_to :project and :project has_many :docs and nesting sees to make logical sense there. I just want to do it the right way.
Benefits: Application layout is reused, simple
Shortcomings: nearly no code-reuse regarding routing is possible (e.g. navigation guards, path definitions)
Benefits: code reuse in navigation, route structure resembles logical structure of entities
Shortcomings: Pages include duplicate code regarding application structure
My preferred approach: Nested routes with layouts
Now we can use the concept of layouts, to enable the pages to reuse application structure. This way we can diminish the shortcomings of the bare nested router approach. But in general the layouts are independent from the routing approach and just a good practice imo.
Layouts are simple components that hold the application structure (nav, footer, side-menu) for different pages.
<template>
<nav/>
<div id="content">
<slot/> <!-- this is where the content will be injected -->
</div>
<footer/>
</template>
That way the pages do not repeat the basic code for application structure. Also you can easily have different layouts for different pages. For example, some pages maybe should have a sidebar, while others shouldn't. This can easily be abstracted from the pages.
If you want to know more about the concept of layouts, I can also write a more detailed post on this. :)
Ok this is helpful, thanks. I hadn't thought of the beforeEnter callbacks. I had been using mounted/created for that in each component, but if I understand it correctly, I like the abstraction. Now I am wondering why we can't just keep reusing the layout stuff in App.vue and do the nesting with your empty parent solution described in your article. I haven't used slots much so that is something I need to learn. So far props have sufficed for me.
I would keep the App.vue and the EmptyRouterViewComponent just empty with the <router-view/>. This way the pages can control the whole appearance (through the layouts). I would let the pages do this (and not the App.vue). Imagine you would hard-code the nav and a side menu into the App.vue and now you want a Login page not to have a side menu. This may be pretty difficult to override that way. When the pages control the layout, this is way more dynamic and adaptable.
You can also take a look at this project, which uses the approach I outline in the comment above, to understand how this would work on a more complex application than the example: github.com/BerniWittmann/cape-fron...
In general slots are a very handy tool, so i would recommand taking a more in-depth look (e.g. named slots). Especially components can profit from slots. For example, a card component that renders some content is more versatile with a slot instead of props for the content.
I’m not sure whether I understand you correctly.
You ask where the difference is between having these nested routes and the approach to not having nested routes and having all of them at the top level of the configuration?
If so, nested routes allow you to reuse code and logic. Imagine a detail view of a product in a store. You have a route to view the single product and edit it. With nested route you can reuse the code required for fetching the product or adding an access control.
In the original vue app, I presume that you have a file App.vue, which essentially serves as the EmptyRouterView for all of your other views, right? Without nesting routes, you could have separate routes like products/:id/details and products/:id/edit, etc. The solution described in the article seems to recreate this structure. If the parent is truly empty (my App.vue actually contains my navigation and notification components) and the others are at the same level, I don't see how you can reuse code any more than I reuse code from App.vue. What am I missing? For example, I am creating a structure that has Projects and Documents s.t. :doc belongs_to :project and :project has_many :docs and nesting sees to make logical sense there. I just want to do it the right way.
Okay first of all let me summarize the two approaches:
First Approach: No Nested Routes
Main
App.vue
includes the application layout with nav, footer etc.The router config has the routes on the top - level
The pages themselves then mainly just contain the content of the page
Benefits: Application layout is reused, simple
Shortcomings: nearly no code-reuse regarding routing is possible (e.g. navigation guards, path definitions)
Second Approach: Nested Routes
The
App.vue
file is just the root router viewThe router config is nested
The pages then contain the whole application code:
Benefits: code reuse in navigation, route structure resembles logical structure of entities
Shortcomings: Pages include duplicate code regarding application structure
My preferred approach: Nested routes with layouts
Now we can use the concept of layouts, to enable the pages to reuse application structure. This way we can diminish the shortcomings of the bare nested router approach. But in general the layouts are independent from the routing approach and just a good practice imo.
Layouts are simple components that hold the application structure (nav, footer, side-menu) for different pages.
Then the pages can use these layouts like so:
That way the pages do not repeat the basic code for application structure. Also you can easily have different layouts for different pages. For example, some pages maybe should have a sidebar, while others shouldn't. This can easily be abstracted from the pages.
If you want to know more about the concept of layouts, I can also write a more detailed post on this. :)
Ok this is helpful, thanks. I hadn't thought of the beforeEnter callbacks. I had been using mounted/created for that in each component, but if I understand it correctly, I like the abstraction. Now I am wondering why we can't just keep reusing the layout stuff in App.vue and do the nesting with your empty parent solution described in your article. I haven't used slots much so that is something I need to learn. So far props have sufficed for me.
I would keep the
App.vue
and theEmptyRouterViewComponent
just empty with the<router-view/>
. This way the pages can control the whole appearance (through the layouts). I would let the pages do this (and not theApp.vue
). Imagine you would hard-code the nav and a side menu into theApp.vue
and now you want a Login page not to have a side menu. This may be pretty difficult to override that way. When the pages control the layout, this is way more dynamic and adaptable.You can also take a look at this project, which uses the approach I outline in the comment above, to understand how this would work on a more complex application than the example: github.com/BerniWittmann/cape-fron...
In general slots are a very handy tool, so i would recommand taking a more in-depth look (e.g. named slots). Especially components can profit from slots. For example, a card component that renders some content is more versatile with a slot instead of props for the content.
Ok. I'm converted. I am going to check out slots.
Thanks again.