1001Songs Clips
1001Songs Clips

Reputation: 59

VueJS: How to make v-for to display 10 items per page?

I have a questionnaire with 60 questions, and I need to display 10 questions at a time.

But, I'm having trouble making it work even though I see some references on the internet.

The way I am doing, each time I click next(), 10 items are added to the v-for, but the previous 10 items remain on the page.

I'm doing this:

<div class="test-questions comp">
                    <div class="question" v-for="q in perguntas['questions']" v-if="q.id <= perpage">
                        <div class="statement">
                            {{q.id}}. {{q.text}}
                        </div>
                        <div class="options yes-no">
                            <div class="caption option yes">Sim</div>
                            <div class="caption option no">Não</div>
                        </div>
                    </div>
                  
                </div>
                <div class="action-row">
                    <button v-if="perpage == 60" @click="salvarRelato()"><span>Publicar</span></button>
                    <button v-if="perpage < 50" @click="previous()"><span>Anterior</span></button>
                    <button v-if="perpage < 50" @click="next()"><span>Próximo</span></button>
                </div>

My data:

props: ['perguntas'],
        data(){
            return {
                perpage: 10,
            }
        },
        methods: {
            next(){
                this.perpage = this.perpage + 10;
            },
            previous(){
        this.perpage = this.perpage - 10;
            },
        }

Can you help me ?

Upvotes: 1

Views: 2568

Answers (3)

Mohammad Basit
Mohammad Basit

Reputation: 575

You can keep an array for questions that need to be rendered and the fill the array with 5 questions whenever loadnext() method is fired which will empty old questions and fill the array with new like this.

Check this out for Live Demo

Vue Markup :

<template>
   <div id="app">
      <div v-for="item in toRender" :key="item" > {{ item.name }} </div>
      <button @click="loadnext()">next</button>
   </div>
</template>

Vue <script> :

data: () => ({
  start: 0, // Lower limit 
  end: 5, // Upper Limit
  questions: [], // Array containing all the questions.
  toRender: [] // Array containing questions that need to be rendered. 
}),

mounted() {
  for (let i = this.start; i < this.end; i++){
    this.toRender.push(this.questions[i])
  }
  this.start = this.start + this.toRender.length;
  this.end =  this.start + this.toRender.length;
}

methods: {
  loadnext() {
    this.toRender = [];
      for (let i = this.start; i < this.end; i++){
        this.toRender.push(this.questions[i])
      }
   }
 } 

Upvotes: 1

Gursewak Singh
Gursewak Singh

Reputation: 822

Why don't you try to keep two arrays (primary, secondary), whenever next() method is called, you get the 10 tracked items from primary arrays and append it to the secondary array. And use v-for on the secondary array to get the all items (previous and the appended ones).

There must be better way to do that, but for time being I can only suggest you this solution.

Upvotes: 0

Boussadjra Brahim
Boussadjra Brahim

Reputation: 1

You should add another property called pageNumber initialized by 1, then use another one defined as computed property called currentPageItems based on pageNumber and perPage then loop through the currentPageItems:

props: ['perguntas'],
        data(){
            return {
                perpage: 10,
                pageNumber:0
            }
        },
      computed:{
        currentPageItems(){
          return this.perguntas.slice(this.pageNumber*this.perpage,this.pageNumber*this.perpage+1+this.perpage)
        }
         }
        methods: {
            next(){
                this.pageNumber++;
            },
            previous(){
           this.pageNumber--;
            },
        }

template :

   v-for="q in currentPageItems"

Upvotes: 2

Related Questions