[Vuejs]-Bind class item in the loop

0👍

You can change your isLoading to an array of booleans, and your addToCart method to also have an index argument.

Data:

return {
  // ...
  isLoading: []
}

Methods:

addToCart(product, index) {
  // ...
}

And on your button, also include index:

@click="addToCart(product, index)"

By changing isLoading to an empty array, I don’t think isLoading[index] = true will be reactive since index on isLoading doesn’t exist yet. So you would use Vue.set in your addToCart(product, index) such as:

this.$set(this.isLoading, index, true)

This will ensure that changes being made to isLoading will be reactive.

Hope this works for you.

0👍

add on data productsLoading: []

on add to cart click, add loop index to productsLoading.
this.productsLoading.push(index)

after http request done, remove index from productsLoading.
this.productsLoading.splice(this.productoading.indexOf(index), 1)

and check button with :loading=productsLoading.includes(index)

0👍

You can create another component only for product card,
for better option as show below
Kindly follow this steps.
place the content of card in another vue component as shown below.

<!-- Product.vue  -->
<template>
<div class="card">
   <div class="card-image">
       <figure class="image is-4by3">
           <img src="" alt="Placeholder image">
        </figure>
    </div>
    <div class="card-content">
      <div class="content">
          <div class="media-content">
              <p class="title is-4">{{product.name}}</p>
              <p class="subtitle is-6">Description</p>
              <p>{{product.price}}</p>
          </div>
      </div>

      <div class="content">
         <b-button class="is-primary" @click="addToCart(product)" :loading="isLoading"><i class="fas fa-shopping-cart"></i> Ajouter au panier</b-button>
       </div>
    </div>
</div>
</templete>
<script>
  export default {
    name: "Product",
    data() {
      return {
        isLoading: false
      }
    },
    props: {
      product: {
        type: Object,
        required: true
      }
    },
    methods: {
     addToCart(product) {
        this.isLoading = true
        axios.post('cart/add-to-cart/', {
           data: product,
        }).then(r => {
          this.isLoading = false
        }).catch(e => {
         this.isLoading = false
        });
    }
   }
 }
</script>

Change your component content as shown below.

<template>
<div class="container column is-9">
    <div class="section">
        <div class="columns is-multiline">
            <div class="column is-3" v-for="(product, index) in computedProducts">
               <product :product="product" />
            </div>
        </div>
    </div>
</div>
</templete>
<script>

  import Product from 'path to above component' 

  export default {
   components: {
     Product 
   }
 }
</script>

so in the above method you can reuse the component in other components as well.

Happy coding 🙂

Leave a comment