1

I have two nested v-for elements that look like:

<div class="category" v-for="(category, categoryIndex) in categories">
    <div class="product" v-for"(product, productIndex) in cateogry)">
        {{product.name}}
    </div>
</div>

I would like to show only the first five products, regardless of the number of categories and the number of products in each category.

How would I get the cumulative index count (in relation to the total number of products that's been displayed from the categoryIndex parent array) inside of the second v-for element?

3
  • Do you mean five products from each category or five products from all categories? Could you provide jsfiddle? Commented May 1, 2020 at 21:42
  • I would loop through the products and categories in your JS and build a new array to loop through in the template. In your category and product loop you could increment a separate count for each product, and if the count is less than 5, add the product to your new array. That way your logic is all in the JS and you keep the template simple. Commented May 1, 2020 at 22:08
  • Maybe a computed property that slice() your products into an array with 5 products. Commented May 1, 2020 at 22:43

2 Answers 2

1

If I understood, it will be something like this

<div class="category" v-for="(category, categoryIndex) in categories">
    {{ category.name }}
    <div class="product" v-for="(product, productIndex) in category.products.slice(0, nbProductToShow)">
        {{(categoryIndex*nbProductToShow)+(productIndex+1)}}
        {{product.name}}
    </div>
</div>

Vue

new Vue({
    data : {
        nbProductToShow : 5,
        categories : [{
                id : 3445,
                name : 'shoes',
                products : [
                    { id: 23234, name : 'Pink unicorn shoes'}, 
                    // ...
                ]
            },{
                id : 3447,
                name : 'hat',
                products : [
                    { id: 232, name : 'Pink long hat with unicorn'}, 
                    // ...
                ]
            }
        ]
    }
})
Sign up to request clarification or add additional context in comments.

1 Comment

You can replace category.products.slice(0, nbProductToShow) by splicedProducts property.
0

You can check if the product is within the first five products rendering by passing its id to a function and showing the product according to its returned value. Here is an example:

<template>
  <div>
    <div class="category" v-for="(category, categoryIndex) in categories" :key="categoryIndex">
      <div class="product" v-for="(product, productIndex) in category.products" :key="productIndex">
        <span v-if="incrementCount(product.id)">{{product.name}}</span>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      categories: [
        {
          products: [
            { id: 1, name: "1" },
            { id: 2, name: "2" },
            { id: 3, name: "3" },
          ]
        },
        {
          products: [
            { id: 4, name: "4" },
            { id: 5, name: "5" },
            { id: 6, name: "6" },
          ]
        }
      ]
    };
  },
  methods: {
    incrementCount: function(id) {
      let count = 0;
      for(let i = 0; i < this.categories.length; i++)
        for(let j = 0; j < this.categories[i].products.length; j++)
          if(count++ < 5 && this.categories[i].products[j].id===id)
            return true;
      return false;
    }
  },
};
</script>

Correspondingly, the output would be:

1
2
3
4
5

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.