vue.jsnuxt.jsvue-router

Nuxt.js router - change route params without re-mounting a new page?


I have a single-page app with Nuxt.js (v 2.15.7) that needs to get two parameters from the URL. For example:

domain.com 
domain.com/chapter3
domain.com/chapter3/section5

All 3 of these addresses should render the same page found in pages/index.vue, I just want to be able to read the $route.params.chapterNo and $route.params.sectionNo as it changes, without really redirecting to a different page.

I've partially accomplished this by editing my nuxt.config.js file as follows:

router: {
  extendRoutes(routes, resolve) {
    routes.push({
      name: 'chapter',
      path: '/chapter:chapterNo?',
      component: resolve(__dirname, 'pages/index.vue')
    });
    routes.push({
      name: 'section',
      path: '/chapter:chapterNo?/section:sectionNo?',
      component: resolve(__dirname, 'pages/index.vue')
    });
  }
},

The only problem is that this destroys the previous version of pages/index.vue and re-mounts a new version of it each time you route to a new chapter or section. mounted() gets called on each route change, but I need the page to be mounted only once. It's going to be animated as the address changes, but with this setup, the whole DOM gets cleared and re-built, removing the possibility for animations. What router config can I use to only get the two params without re-rendering the whole page?

I've tried removing the component property of the config file, but that gives me page not found errors.

Attempt 1:

I tried using keep-alive on the root <Nuxt> component, but this only caches each page. It still gets re-mounted once on each route change.

Attempt 2:

I tried the router-extras module with the define multiple parameters option, but that also re-mounts pages/index.vue each time the route changes. This is my attempt, which yields the same issue:

<router>
{
    path: '/chapter:chapterNo?/mission:missionNo?',
}
</router>

Is there any way to change routes to get the parameters without re-mounting pages.index.vue?


Solution

  • I was looking at the Vue developer tools with <Nuxt keep-alive /> in my default layouts file, and noticed that Nuxt was creating a new instance of pages/index.vue with a unique key for each chapter and section:

    enter image description here

    This gave me the idea to forcefully assign a constant key to the page by using

    <Nuxt nuxt-child-key="doNotReMount"/>.

    enter image description here

    Now that the key doesn't update on each new route, the pages/index.vue page is only mounted once, and all subsequent routes use the same instance of this page!