如何在 vue 中计算 increment/decrement 购物车

How to make increment/decrement cart count in vue

我创建了一个递增和递减函数,这样我就可以更改 cards.count 中的 count

增加count的函数是这样的

但是递减函数count,它不起作用。

当我点击递减函数时,会出现这样的输出

Error in v-on handler: "TypeError: Cannot read property 'product_id' of undefined"

虽然自增函数也有product_id.

,但不知道为什么product_id会报错

希望你能帮我解决问题

       <template>
        <div v-if="cartList && cartList.length > 0">
          <div
            class="item-loop container col"
            v-for="(cards, index) in cartList"
            :key="generateKey(cards.product_id, cards.count)"
          >
            <div class="items row">
              <div class="image col-4">
                <img class="img-fluid pt-2" :src="cards.product_img" />
              </div>
              <div class="content text-left col-8">
                <button
                  v-on:click="cartList.splice(index, 1)"
                  type="button"
                  class="close"
                  data-dismiss="modal"
                  aria-label="Close"
                >
                  <span aria-hidden="true">&times;</span>
                </button>
                <h5 class="text-left">{{ cards.product_name }}</h5>
                <div class="prices" :key="cards.product_id">
                  <div class="value-cart form-group row">
                    <font-awesome-icon
                      :icon="['far', 'minus-square']"
                      size="2x"
                      class="minus-button"
                      @click="min(cards.product_id)"
                    />
                    <input
                      type="number"
                      class="input-pm bg-light form-control p-0 text-center angka"
                      :value="cards.count"
                    />
                    <font-awesome-icon
                      :icon="['far', 'plus-square']"
                      size="2x"
                      class="plus-button"
                      @click="plus(cards.product_id)"
                    />
                  </div>
                  <p>Rp. {{ cards.product_price * cards.count }}</p>
                </div>
              </div>
            </div>
          </div>
          <div class="cart-order">
            <div class="order-total">
              <div class="row">
                <h4 class="col-6 font-weight-bold text-left">Total</h4>
                <h5 class="col-6 font-weight-bold text-right">
                  Rp. {{ totalprice }}
                </h5>
              </div>
            </div>
            <p class="text-left"><strong>*Not including tax(10%)</strong></p>
            <b-button
              class="mt-3"
              variant="primary"
              @click="invoice()"
              v-b-modal="'modal-checkout'"
              block
              >Checkout</b-button
            >
            <b-button class="mt-2" variant="danger" @click="resetcart" block>
              Cancel </b-button
            ><br /><br />
          </div>
        </div>
      </template>
 
export default {
  components: {
    Features,
    Card,
  },
  data() {
    return {
      datamenu: {},
      cartList: [],
      invoiceid: 0,
      tax: 0,
      searchMenu: null,
      menu: null,
      formCheck: {
        amount: 0,
        invoice: "",
        cashier: "abiwardani",
        menu_name: "",
      },
    };
  },
  methods: {
 plus(product_id) {
      let result = this.cartList.find((res) => {
        if (res.product_id == product_id) {
          return res.product_id;
        }
      });

      if (result) {
        for (let i = 0; i < this.cartList.length; i++) {
          if (this.cartList[i].product_id == product_id) {
            const newFoodObject = {
              ...this.cartList[i],
              count: this.cartList[i].count + 1,             
            };
            console.log("plus");
            this.$set(this.cartList, i, newFoodObject);
          }
        }
      }
    },
    min(product_id) {
      let result = this.cartList.find((res) => {
        if (res.product_id == product_id) {
          return res.product_id;
        }
      });

      if (result) {
        for (let i = this.cartList.length; i > 0; i--) {
          if (this.cartList[i].product_id == product_id && this.cartList[i].count > 0){
            const newFoodObject = {
              ...this.cartList[i],
              count: this.cartList[i].count - 1,
            };
            this.$set(this.cartList, i, newFoodObject);
          }
        }
      }
    },
generateKey(key1, key2) {
      return `${key1}-${key2}`;
    },
},
mounted() {
    axios
      .get(process.env.VUE_APP_URL + "product")
      .then((res) => {
        this.datamenu = res.data.result;
      })
      .catch((err) => {
        console.log(err);
      });
}

您的问题出在 min() 方法中 for 语句最终表达式

将 'i--' 更改为 'i++' 以在每次迭代中增加索引。这将避免访问具有负索引的 'cartList' 数组(这是导致问题的原因,因为它未定义):

min(product_id) {
  let result = this.cartList.find((res) => {
    if (res.product_id == product_id) {
      return res.product_id
    }
  })

  if (result) {
    for (let i = this.cartList.length; i > 0; i++) {
                                               
      ...

我是这样做的

HTML:

<button @click="increment()">+</button>
<input :value="amount" />
<button @click="decrement()">-</button>

JS:

  data() {
    return {
      amount: 0,
    };
  },
  methods: {
    increment() {
      this.amount++;
    },

    decrement() {
      this.amount--;
    },
  },

选项 1: i 应该从 length-1 开始,并且应该上升到 0

min(product_id) {
      let result = this.cartList.find((res) => {
        if (res.product_id == product_id) {
          return res.product_id;
        }
      });

      if (result) {
        for (let i = this.cartList.length-1; i >= 0; i--) {
          if (this.cartList[i].product_id == product_id && this.cartList[i].count > 0){
            const newFoodObject = {
              ...this.cartList[i],
              count: this.cartList[i].count - 1,
            };
            this.$set(this.cartList, i, newFoodObject);
          }
        }
      }

选项 2: 您不需要 2 种方法.. 只需一种

updateQty(product_id,mode) {
      let result = this.cartList.find((res) => {
        if (res.product_id == product_id) {
          return res.product_id;
        }
      });

      if (result) {
        for (let i = 0; i < this.cartList.length; i++) {
          if (this.cartList[i].product_id == product_id) {
            const newFoodObject = {
              ...this.cartList[i],
              count: mode === 'INCRE' ? this.cartList[i].count + 1 : this.cartList[i].count - 1,             
            };
            console.log("plus");
            this.$set(this.cartList, i, newFoodObject);
          }
        }
      }
    },

像这样使用它

 <font-awesome-icon
                      :icon="['far', 'minus-square']"
                      size="2x"
                      class="minus-button"
                      @click="updateQty(cards.product_id,'INCRE')"
                    />

 <font-awesome-icon
                      :icon="['far', 'minus-square']"
                      size="2x"
                      class="minus-button"
                      @click="updateQty(cards.product_id,'DECRE')"
                    />