<div id="app">
  <div class="container-fluid">
    <div class="row no-gutters align-items-center mt-5">
      <div class="col-4">
        <div class="row align-items-baseline no-gutters justify-content-space-between">
          <div>items per page</div>
          <select class="form-control" style="width: 80px; margin-left: 10px;" v-model="totalRowsPerPage">
            <option>5</option>
            <option>10</option>
            <option>15</option>
          </select>
        </div>
      </div>
      <div class="col-8">
        <div class="row justify-content-start">
          <div> showing {{ rangeStart }} - {{ rangeEnd}} of {{totalItems}} </div>
          <div class="pointer ml" @click="move(-1)"><span>
              << </span>Prev </div>
          <div @click="setCurrentPage(page)" class="d-flex pointer btn btn-success btn-xs" style="margin:0 4px;" v-for="page in pages" :key="page" :class="currPage == page ? 'active': ''">{{page}}</div>
          <div class="pointer ml" @click="move(1)">Next >></div>
        </div>
      </div>
    </div>
    <div class=" row" style="margin-top: 3px;">
      <div>
        <table id="table" class="table">
          <thead class="thead-dark">
            <tr>
              <td scope="col" v-for="h in headers" :key="h.value">{{h.text}}</td>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(row, index) in rows" :key="row.name">
              <td v-for="header in headers">
                {{ row[header.value] }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</div>
label {
  font-size: 20px;
  color: tomato;
}
.mt-5 {
  margin-top: 5;
}
.ml {
  margin-left: 5px;
}
.pointer {
  color: blue;
  cursor: pointer;
}
.pa-2 {
  padding: 0 2px;
}
.btn {
  color: ghostwhite;
}
new Vue({
  el: "#app",
  data() {
    return {
      totalRowsPerPage: 5,
      showDetailView: true,
      currPage: 1,
      rows: [],
      headers: [
        {
          text: "Food (100g serving)",
          value: "name"
        },
        {
          text: "Calories",
          value: "calories"
        },
        {
          text: "Protein (g)",
          value: "protein"
        },
        {
          text: "Fat (g)",
          value: "fat"
        },
        {
          text: "Carbs (g)",
          value: "carb"
        },

        {
          text: "Fiber (g)",
          value: "fiber"
        }
      ],
      foods: [
        {
          name: "Chicken",
          carb: 0,
          fat: 14,
          protein: 27,
          fiber: 0,
          calories: 234
        },
        {
          name: "Egg",
          carb: 0,
          fat: 14,
          protein: 27,
          fiber: 0,
          calories: 234
        },

        {
          name: "Oats",
          carb: 66.27,
          fat: 6.9,
          protein: 16.89,
          fiber: 10.6,
          calories: 394.74
        },

        {
          name: "Sprouts",
          carb: 5.94,
          fat: 0.18,
          protein: 3.04,
          fiber: 1.8,
          calories: 37.54
        },
        {
          name: "White rice",
          carb: 44.08,
          fat: 0.44,
          protein: 4.2,
          fiber: 0.6,
          calories: 197.08
        },
        {
          name: "Toor dal",
          carb: 26.18,
          fat: 6.32,
          protein: 10.36,
          fiber: 8.7,
          calories: 203.04
        },
        {
          name: "Curd",
          carb: 3.45,
          fat: 4.2,
          protein: 11.75,
          fiber: 0,
          calories: 98.6
        },
        {
          name: "Soya chunks",
          carb: 15,
          fat: 0,
          protein: 24,
          fiber: 2,
          calories: 156
        },
        {
          name: "Tofu",
          carb: 1.9,
          fat: 5,
          protein: 16,
          fiber: 1,
          calories: 116.6
        },
        {
          name: "Prawn",
          carb: 2,
          fat: 0,
          protein: 24,
          fiber: 1,
          calories: 104
        },

        {
          name: "Fish",
          carb: 0,
          fat: 12,
          protein: 22,
          fiber: 1,
          calories: 196
        },
        {
          name: "Egg White",
          carb: 0.7,
          fat: 0,
          protein: 4,
          fiber: 0,
          calories: 18.8
        },
        {
          name: "Crab",
          carb: 0,
          fat: 0.7,
          protein: 18,
          fiber: 0,
          calories: 78.3
        },
        {
          name: "Sweet Potato",
          carb: 20,
          fat: 0.1,
          protein: 1.6,
          fiber: 3,
          calories: 87.3
        },
        {
          name: "Yam",
          carb: 28,
          fat: 0.2,
          protein: 1.5,
          fiber: 4.1,
          calories: 119.8
        },
        {
          name: "Carrot",
          carb: 10,
          fat: 0.2,
          protein: 1,
          fiber: 2.8,
          calories: 45.8
        }
      ]
    };
  },
  computed: {
    rangeStart() {
      if (this.currPage === 1) {
        return 1;
      }
      return (this.currPage - 1) * this.totalRowsPerPage + 1;
    },
    rangeEnd() {
      if (this.currPage === 1) {
        return this.totalRowsPerPage;
      }
      let end = this.rangeStart + this.totalRowsPerPage;
      if (end > this.totalItems) return this.totalItems;
      else return end;
    },
    pages() {
      return Math.ceil(this.totalItems / this.totalRowsPerPage);
    },
    totalItems() {
      return this.foods.length;
    }
  },
  watch: {
    totalRowsPerPage(pagePerRows) {
      this.fetchFoodItems(0, pagePerRows);
    },
    currPage(page) {
      let offset = 0;
      if (page > 1) {
        offset = this.totalRowsPerPage * (page - 1);
      }
      let limit = offset + this.totalRowsPerPage;
      this.fetchFoodItems(offset, limit);
    }
  },
  methods: {
    setCurrentPage(page) {
      this.currPage = page;
    },
    //default is 5
    fetchFoodItems(offset, limit) {
      this.rows = this.foods.slice(offset, limit);
    },
    move(direction) {
      if (direction == 1) {
        if (this.currPage !== this.pages) {
          this.currPage += 1;
        }
      } else {
        if (this.currPage > 1) {
          this.currPage -= 1;
        }
      }
    }
  },
  created() {
    this.fetchFoodItems(this.offset, this.totalRowsPerPage);
  }
});
View Compiled

External CSS

  1. https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css

External JavaScript

  1. https://cdn.jsdelivr.net/npm/babel-polyfill/dist/polyfill.min.js
  2. https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js
  3. https://code.jquery.com/jquery-3.5.1.slim.min.js
  4. https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js