vue | javascript

Vue.js List Rendering : Limit items in v-for

One way to limit the iteration of items in Vue v-for directive.

Abhith Rajan
Abhith RajanFebruary 27, 2018 · 3 min read · Last Updated:

Today I had to render 200+ items in a bootstrap table which didn’t appear to be user-friendly. So I planned to show first 20 of them on load, and if the user wanted, show full items.

To do that, my Vue app code looks like this,

var app = new Vue({
  el: "#app",
  data: {
    countries: [],
    isLoadingCountries: false,
    showLessCountries: true,
  },
  methods: {
    getCountries: function () {
      app.isLoadingCountries = true;
      app.$http
        .get("some-url")
        .then(function (response) {
          if (response.data) {
            if (response.data.isSuccess) {
              app.countries = response.data.countries;
            }
          }
        })
        .then(function () {
          app.isLoadingCountries = false;
        });
    },
  },
  created: function () {
    this.getCountries();
  },
});

Basically, it contains an array, one flag to indicate the data fetch operation is ongoing or not, one flag to indicate whether the full list is showing or fewer items, and a function to fill the data in the array. I hope the naming convention in the code is pretty self-explanatory.

And my markup,

<table class="table" v-if="!isLoadingCountries">
  <thead>
    <tr>
      <th scope="col">Country</th>
    </tr>
  </thead>
  <tbody v-if="showLessCountries">
    <tr v-for="country in countries.slice(0, 20)">
      <td><h5>{{country.name}}</h5></td>
    </tr>
  </tbody>
  <tbody v-else>
    <tr v-for="country in countries">
      <td><h5>{{country.name}}</h5></td>
    </tr>
  </tbody>
</table>
<button
  v-if="!isLoadingCountries"
  @@click="showLessCountries = !showLessCountries"
>
  {{showLessCountries===true? "Show All Countries" : "Show Less"}}
</button>

Here, Using Array.slice(), we get a new array with the limited number of items from the original array. And we show the new sliced array items or the original array full items based on the flag. And a button to toggle the flag. If you wonder why I used **@@**click in Vue, is because my markup was written in Razor (.cshtml).

Update 1 - Sep 6, 2018

As Andrew Butler pointed out in the comments, we can avoid the markup duplication by using a computed property. And the code becomes,

var app = new Vue({
  el: "#app",
  data: {
    countries: [],
    isLoadingCountries: false,
    showLessCountries: true,
  },
  computed: {
    countriesToDisplay: function () {
      if (this.showLessCountries) {
        return this.countries.slice(0, 10);
      } else {
        return this.countries;
      }
    },
  },
  methods: {
    getCountries: function () {
      app.isLoadingCountries = true;
      app.$http
        .get("some-url")
        .then(function (response) {
          if (response.data) {
            if (response.data.isSuccess) {
              app.countries = response.data.countries;
            }
          }
        })
        .then(function () {
          app.isLoadingCountries = false;
        });
    },
  },
  created: function () {
    this.getCountries();
  },
});

And the markup,

<table class="table" v-if="!isLoadingCountries">
  <thead>
    <tr>
      <th scope="col">Country</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="country in countriesToDisplay">
      <td>
        <h5>{{country.name}}</h5>
      </td>
    </tr>
  </tbody>
</table>
<button
  v-if="!isLoadingCountries"
  @@click="showLessCountries = !showLessCountries"
>
  {{showLessCountries===true? "Show All Countries" : "Show Less"}}
</button>

If you know a better way to do the same, let me know.

Additional Resources

This page is open source. Noticed a typo? Or something unclear?
Improve this page on GitHub


Abhith Rajan

Written byAbhith Rajan
Abhith Rajan is a software engineer by day and a full-stack developer by night. He's coding for almost a decade now. He codes 🧑‍💻, write ✍️, learn 📖 and advocate 👍.
Connect

Is this page helpful?

Related SnippetsView All

Related ArticlesView All

Related VideosView All

Why pnpm?

Easy NPM Package Updates with Yarn Upgrade Interactive

Single Page Architectures with VueJS and ASP.NET Core - Kevin Griffin