0

I am newbie to Vue and arrays. I want to paginate my json array and limit it to 10 items only per page. However in my <tr> body it shows all the list in the array. I tried some other way but it didnt work. Can anyone help me find the best way to paginate this json array and reflect in my table? Thank you.

This is the code:

https://codesandbox.io/s/exciting-kapitsa-8d46t?file=/src/App.vue:1415-2437

App.vue

<template>
  <div id="app">
    <table class="table t3">
      <thead class="thead">
        <tr class="tr">
          <th class="td no" width="10%">
            <span class="has-text-orange">No</span>
          </th>
          <th class="td">
            <span class="has-text-orange">Name</span>
          </th>
        </tr>
      </thead>
      <tbody
        class="searchable tbody"
        style="max-height: 200px; min-height: 200px"
      >
        <tr class="tr" v-for="(p, index) in alphabets" :key="index">
          <td class="td no" width="10%">{{ ++index }}</td>
          <td class="td">{{ p.letter }}</td>
        </tr>
      </tbody>
    </table>
    <div class="column is-12">
      <nav
        class="pagination is-right"
        role="navigation"
        aria-label="pagination"
      >
        <ul class="pagination-list">
          <li>
            <a @click="prev"> Prev </a>
          </li>
          <li>
            <span
              class="pagination-link go-to has-text-orange"
              aria-label="Goto page 1"
              >{{ current }}</span
            >
          </li>
          <li>
            <a @click="next()"> Next </a>
          </li>

          <li>
            <input type="text" class="pagination-link" />
          </li>
          <li>
            <button class="button">Go</button>
          </li>
        </ul>
      </nav>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  components: {},
  data() {
    return {
      current: 1,
      alphabets: [
        { letter: "a" },
        { letter: "b" },
        { letter: "c" },
        { letter: "d" },
        { letter: "e" },
        { letter: "f" },
        { letter: "g" },
        { letter: "h" },
        { letter: "i" },
        { letter: "j" },
        { letter: "k" },
        { letter: "l" },
        { letter: "m" },
        { letter: "n" },
        { letter: "o" },
        { letter: "p" },
        { letter: "q" },
        { letter: "r" },
        { letter: "s" },
        { letter: "t" },
        { letter: "u" },
        { letter: "v" },
        { letter: "w" },
        { letter: "x" },
        { letter: "y" },
        { letter: "z" },
      ],
    };
  },
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

1 Answer 1

11

Loop through a reduced set instead of all data. You have a current page; create a property for pageSize:

pageSize: 10

Calculate the index boundaries of the reduced set, changing whenever current changes (or pageSize):

computed: {
  indexStart() {
    return (this.current - 1) * this.pageSize;
  },
  indexEnd() {
    return this.indexStart + this.pageSize;
  },
},

Use another computed to derive the reduced set from the boundaries:

paginated() {
   return this.alphabets.slice(this.indexStart, this.indexEnd);
}

Loop through the reduced set instead of all data:

v-for="(p, index) in paginated"

Here is your updated demo (you will have to fix the next & prev buttons when they overflow):

new Vue({
  el: "#app",
  data() {
    return {
      current: 1,
      pageSize: 10,
      alphabets: [
        { letter: "a" },
        { letter: "b" },
        { letter: "c" },
        { letter: "d" },
        { letter: "e" },
        { letter: "f" },
        { letter: "g" },
        { letter: "h" },
        { letter: "i" },
        { letter: "j" },
        { letter: "k" },
        { letter: "l" },
        { letter: "m" },
        { letter: "n" },
        { letter: "o" },
        { letter: "p" },
        { letter: "q" },
        { letter: "r" },
        { letter: "s" },
        { letter: "t" },
        { letter: "u" },
        { letter: "v" },
        { letter: "w" },
        { letter: "x" },
        { letter: "y" },
        { letter: "z" },
      ],
    };
  },
  computed: {
    indexStart() {
      return (this.current - 1) * this.pageSize;
    },
    indexEnd() {
      return this.indexStart + this.pageSize;
    },
    paginated() {
      return this.alphabets.slice(this.indexStart, this.indexEnd);
    }
  },
  methods: {
    prev() {
      this.current--;
    },
    next() {
      this.current++;
    }
  }
});
<div id="app">
    <table class="table t3">
      <thead class="thead">
        <tr class="tr">
          <th class="td no" width="10%">
            <span class="has-text-orange">No</span>
          </th>
          <th class="td">
            <span class="has-text-orange">Name</span>
          </th>
        </tr>
      </thead>
      <tbody
        class="searchable tbody"
        style="max-height: 200px; min-height: 200px"
      >
        <tr class="tr" v-for="(p, index) in paginated" :key="index">
          <td class="td no" width="10%">{{ indexStart + ++index }}</td>
          <td class="td">{{ p.letter }}</td>
        </tr>
      </tbody>
    </table>
    <div class="column is-12">
      <nav
        class="pagination is-right"
        role="navigation"
        aria-label="pagination"
      >
        <ul class="pagination-list">
          <li>
            <a @click="prev"> Prev </a>
          </li>
          <li>
            <span
              class="pagination-link go-to has-text-orange"
              aria-label="Goto page 1"
              >{{ current }}</span
            >
          </li>
          <li>
            <a @click="next()"> Next </a>
          </li>

          <li>
            <input type="text" class="pagination-link" />
          </li>
          <li>
            <button class="button">Go</button>
          </li>
        </ul>
      </nav>
    </div>
  </div>
  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/buefy/0.9.4/buefy.min.css" integrity="sha512-kYGHZRStwK4F8bgVhj/J5IEWmEjLbQ7re6mQiYx/LH5pfl8bDQ3g5SaExM/6z59mASfENR8xwVhywnm8ulVvew==" crossorigin="anonymous" />

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.