如何在 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">×</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')"
/>
我创建了一个递增和递减函数,这样我就可以更改 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">×</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')"
/>