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

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

commit 940f685 · authored · amended · 3 min read

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

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

local graph · open full graph

"Vue.js List Rendering : Limit items in v-for" is connected to the topics Vue.js, JavaScript and related to 6 other entries. JavaScript - Determine if user is on mobile device JavaScript - Determine if u… Remove specific class from all elements - jQuery Remove specific class from … Get/Set hidden field value using jQuery Get/Set hidden field value … Set selected option by value via jQuery Set selected option by valu… Decode JWT Token Decode JWT Token Domain Name From URL Domain Name From URL Vue.js #vue JavaScript #javascript Vue.js List Rendering : Limit ite…

comments

loading discussion…