Search code examples
vue.jsvuejs3vue-router4

Vue Router - Nested Routes Not Working as Expected


I'm trying to create a simple nested routing:

  • App (root component, main navigation)
  • Topic1 (sub-navigation)
    • Topic1/Sub
  • Topic2

My demo on Codesandbox has the following issues:

1. When navigating from /topic1 to /topic1/sub, I expected the content from topic1 to show up and the content from topic1/sub to be shown below, like this:

Expected result

However, Topic 1 does not show anymore.

2. How can I avoid showing "App" twice?

Unexpected result

I know I've added path: "/topic1", component: App, but only because without it the routing did not work at all. As per the comments in router/index.js:

component: App, // Option 1 - Navigation to topic1,2 and /sub works (why?) 'App' is displayed twice
component: Topic1, // Option 2 - Navigation to /sub does not work but at least 'App' is only displayed once

I seem to be missing something essential - thank you already for any answers.


Solution

  • App component is showing twice because it is mounted twice. First it is mounted in main.js when you create the app. Then it is mounted in router-view as the route component. To avoid this, you shouldn't use the App component in router, instead make another Layout component where you define the page layout to be used by the vue-router. Also, this will allow the scenario where, while having a single entry point for your app (App), you can define different layouts for different routes, if needed.

    Regarding the first question, the content of Topic1 component is not shown when navigating to Sub route, because it is wrapped in router-view. router-view displays only the content of the current route component. Avoid placing any content in router-view as it will be replaced on route navigation. This will work:

    <h1>Topic1</h1>
    
    <h2>Topic1 Content</h2>
    <p>
        <router-link to="/topic1/Sub">/topic1/sub</router-link>
    </p>
    <router-view> </router-view>
    

    Here is the working codesandbox. Also I refactored a bit your router index.js.