Home > Back-end >  How to update data in a table, shopping cart style? Vue
How to update data in a table, shopping cart style? Vue

Time:06-14

I am learning Vue and I am making a shopping cart style table, I have the problem that when I INCREASE and DECREASE from the table the quantity does not increase or decrease in the visual part, but if I inspect the component and the data inside the array if the quantity is updated, I attach image.

enter image description here

I attach an image of how is the table, as you can see it is a simple common table of a shopping cart, I saw other tutorials or people who have done it but it still does not work, I do not know if I'm missing something else or I'm doing wrong the part of auto increase the amount of the row.

enter image description here

Attached is the script code and template

                <table  ref="table">
                    <thead>
                        <th
                            v-for="(head, key) in fields"
                            :key="key"
                            v-text="head"
                        ></th>
                    </thead>
                    <tbody v-if="items.length > 0">
                        <tr v-for="(product, i) in items" :key="i">
                            <td v-text="product.code"></td>
                            <td v-text="product.name"></td>
                            <td>
                                ${{ Number(product.price).toLocaleString() }}
                            </td>
                            <td width="200">
                                <!-- <b-form-input type="number" min="0"  size="sm" :value="product.stock" @change="changeStock(i)"></b-form-input> -->
                                <a
                                    
                                    @click="decrement(i)"
                                    v-bind:disabled="product.count <= 1"
                                    >-</a
                                ><!-- v-bind:disabled="product.count<=1" -->
                                {{ product.count }}
                                <a
                                    
                                    @click="increment(i)"
                                    > </a
                                >
                            </td>
                            <td width="200">
                                <b-input-group>
                                    <b-form-input
                                        type="number"
                                        min="0.00"
                                        
                                        size="sm"
                                        value="0"
                                    ></b-form-input>
                                    <b-input-group-append>
                                        <b-input-group-text>
                                            %
                                        </b-input-group-text>
                                    </b-input-group-append>
                                </b-input-group>
                            </td>
                            <td>${{ sumTotalproduct(product.price) }}</td>
                            <td width="10">
                                <a
                                    href="#"
                                    v-b-tooltip.hover
                                    title="Quitar de la cotización"
                                    @click="deleteItem(i)"
                                    ><i
                                        
                                    ></i
                                ></a>
                            </td>
                        </tr>
                        <tr>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td>NETO</td>
                            <td colspan="2">
                                ${{ Number(totalNeto).toLocaleString() }}
                            </td>
                        </tr>
                        <tr>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td>IVA (19%)</td>
                            <td colspan="2">
                                ${{ Number(totalIVA).toLocaleString() }}
                            </td>
                        </tr>
                        <tr>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td></td>
                            <td>TOTAL</td>
                            <td colspan="2">
                                ${{ Number(total).toLocaleString() }}
                            </td>
                        </tr>
                    </tbody>
                </table>

export default {
    name: 'Quote',
    data () {
        return {
            fields: [
                'Código',
                'Producto',
                'Precio',
                'Cantidad',
                'Descuento',
                'Total',
                'Acción'
            ],
            items: [],
            hover: true,
            dark: false,
            noCollapse: true,
            headVariant: null,
            tableVariant: '',
            productSelected: null,
            options: [],
            chooseProduct: null,
            products: []
        }
    },
    created () {
        this.getProducts()
    },
    computed: {
        totalNeto: function () {
            var sum = 0
            this.items.forEach(e => {
                sum  = e.price
            })

            return sum
        },
        totalIVA: function () {
            return parseInt(this.totalNeto * 0.19)
        },
        total: function () {
            return this.totalNeto   this.totalIVA
        },
    },
    methods: {
        openSideBarModal () {
            this.$root.$emit('bv::toggle::collapse', 'my-sidebar')
        },
        getProducts () {
            axios.get(route('products.listAll')).then(res => {
                this.options = res.data.data
            })
        },
        currentDataItems () {
            var stock = 1
            // Obtenemos los datos del producto.
            var data = this.options.find(p => p.id == this.chooseProduct.id)

            // Validamos que no exista el dato ya en la tabla.
            if (this.items.length > 0) {
                var existData = this.items.some(d => d.id == data.id)
                if (!existData) {
                    data.count = 1 //data.stock   stock
                    this.items.push(data)
                    // }else{
                    //     data.stock  = data.stock   stock
                }

                return
            }

            data.count = 1
            this.items.push(data)
            console.log(this.items)
        },
        sumTotalproduct (price) {
            return Number(price).toLocaleString()
        },
        increment (i) {
            this.items[i].count  
        },
        decrement (i) {
            if (this.items[i].count == 0) return
            this.items[i].count--
        },
        deleteItem (index) {
            Swal.fire({
                title: '¿Estas seguro de quitar el producto?',
                text:
                    'Recuerda, que puedes volver a añadir al carro el producto.',
                icon: 'warning',
                showCancelButton: true,
                confirmButtonColor: '#283669',
                cancelButtonColor: '#d33',
                confirmButtonText: 'Si, quitar!'
            }).then(result => {
                if (result.isConfirmed) {
                    this.items.splice(index, 1)

                    Swal.fire(
                        'Eliminado!',
                        'El producto se a elimina de la cotización.',
                        'success'
                    )
                }
            })
        }
    }
}

CodePudding user response:

I am not sure what issue you are facing but it is working fine for me. I juts created a working code snippet. Please have a look and let me know if any further changes required in that.

new Vue({
  el: '#app',
  data: {
    items: [{
      count: 0
    }, {
      count: 0
    }, {
      count: 0
    }, {
      count: 0
    }, {
      count: 0
    }]
  },
  methods: {
    increment (i) {
      this.items[i].count  
    },
    decrement (i) {
      if (this.items[i].count == 0) return
      this.items[i].count--
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
  <div v-for="(product, i) in items" :key="i">
    <button @click="decrement(i)"
       v-bind:disabled="product.count <= 1">-</button>
    {{ product.count }}
    <button @click="increment(i)"> </button>
  </div>
</div>

CodePudding user response:

Try this...

increment (i) {
  this.$set(this.items[i], 'count', this.items[i].count   1)
},
decrement (i) {
  if (this.items[i].count == 0) return
  this.$set(this.items[i], 'count', this.items[i].count - 1)
}

CodePudding user response:

The issue here likely has to do with Vue 2's reactivity system. When you change a member of an object or array, Vue only knows to watch for and react to it if it is defined in the vue object or if you tell it to by using Vue.set(). if you change your code to this it should work.

increment(i) {
  this.$set(this.items[i], count, this.items[i]   1);
},
decrement(i) {
  if (!this.items[i].count) return;
  this.$set(this.items[i], count, this.items[i] - 1);
}

Rohìt's answer worked because he defined all the objects in the data function.

  • Related