Search code examples
javascriptvue.jsvuexnuxt.js

Generate 'X' number of pages from object using Nuxt JS / Vue JS?


I am currently creating a "Static Generated" site using NuxtJS version "^2.0.0" (I believe it to be 2.13.x).

I have created a Vuex 'store' from which I plan to pull data to aid in my static generation process. For example I plan to have an array Articles within the store containing an object for each article on the site.

My primary question is this: is is possible to render an 'X' amount of these articles (let's say 5) per page and then have NuxtJS automatically generate a new page to contain the next 5 until the source array (Articles) runs out of objects?

I understand that NuxtJS provides route generation, but is it possible for it to also statically generate a new page corresponding to each new route? I believe my request is different from Dynamic Routes, but please correct me if I am mistaken.

Likewise, config generate option doesn't seem to exactly fit what I'm describing although I admit I don't fully understand its documentation.


Solution

  • I'd like to thank @s4k1b for the advice. Some continued reading and their guidance helped me realize that I need to use Dynamic Routing.

    I did not realize this at first as I was using nested routing (unnecessarily) for these pages which does not play well with dynamic routing. Substituting the nested routing for dynamic routing allowed me to reference the URL parameters (i.e. /writing/1, the number '1') which I then used in my v-for logic to achieve the desired affect.

    The end result looks something like this:

    <post
            v-for="index in postCount" :key="index"
            :showBadge="false"
            :title="projects[index + indexAdjust].title"
            :subtitle="projects[index + indexAdjust].subtitle"
            :date="projects[index + indexAdjust].date"
            :tag="projects[index + indexAdjust].tag"
            :url="projects[index + indexAdjust].url">
            {{ projects[index + indexAdjust].body }}
            </post>
    

    ...

    data () {
        return {
          projects: this.$store.state.main.projects,
          blogsPerPage: this.$store.state.main.blogsPerPage,
          router: this.$route.params
        }
      },
      computed: {
        postCount () {
          let value = this.blogsPerPage
          if (parseInt(this.router.page) === Math.ceil(this.projects.length / this.blogsPerPage)) {
            // if on the last page
            value = this.projects.length % this.blogsPerPage
          }
          return value
        },
        indexAdjust () {
          let value = (this.blogsPerPage * (parseInt(this.router.page) - 1)) - 1
          return value
        }
      },
    

    Basically: iterate the post component for blogsPerPage amount of times on each page unless we are on the final page then only loop for the modulus of the total number of posts by the number of postsPerPage to only display the remaining post content.

    The indexAdjust computed value simply counts the number of posts from our Vuex store should have already been rendered on previous pages. For this we take the previous page's number (parseInt(this.router.page) - 1 and multiply it by the number of posts per page. Since v-for starts at 1 when iterating by a static number and not through a Javascript object we subtract by 1 to start at the 0 position in our store Array.