vue+vant实现购物车全选、单个删除功能
效果展示

一、html代码
<div class="cart">
<ul class="cart-list">
<li
class="goods"
v-for="(item, index) in cartList"
:key="item._id + index"
>
<van-checkbox v-model="item.checked"></van-checkbox>
<div class="good_img">
<img :src="item.product.coverImg" alt="" />
</div>
<div class="goods-r">
<h4>{{ item.product.name }}</h4>
<div class="goods-price-num">
<span class="goods-price"
>¥
<b>{{ item.product.price }}</b>
</span>
<span class="goods-num">
<span
@click="item.quantity > 1 && updatePro(item.product._id, -1)"
>-</span
>
<i> {{ item.quantity }} </i>
<span @click="updatePro(item.product._id, 1)">+</span>
<span v-if="item.checked" class="del" @click="del(item._id)">
×
</span>
</span>
</div>
</div>
</li>
</ul>
<van-submit-bar
:price="sumPrice * 100"
button-text="立即结算"
@submit="onSubmit"
>
<van-checkbox v-model="checked">全选</van-checkbox>
<van-icon name="delete" v-show="checked" @click="dels" />
</van-submit-bar>
</div>
二、 标题js代码
import { reqCartAPI, addCartAPI, deleProAPI } from "../../api/cart";
import { orderAPI } from "../../api/order";
export default {
components: {},
data() {
return {
cartList: [],
};
},
computed: {
sumPrice() {
return this.cartList
.filter((item) => item.checked)
.reduce((pre, cur) => {
return pre + cur.product.price * cur.quantity;
}, 0);
},
selectedProduct() {
let selectArr = [];
this.cartList.forEach((item) => {
if (item.checked) {
selectArr.push({
quantity: item.quantity,
product: item._id,
price: item.product.price,
});
}
});
return selectArr;
},
checked: {
set(flag) {
console.log(flag);
this.cartList.map((item) => this.$set(item, "checked", flag));
},
get() {
return (
this.cartList.length ==
this.cartList.filter((data) => data.checked == true).length
);
},
},
},
watch: {},
methods: {
async getCartData() {
const res = await reqCartAPI();
if (res.status == 200) {
this.cartList = res.data;
console.log(this.cartList);
}
},
async updatePro(id, num) {
await addCartAPI(id, num);
this.cartList.forEach((item) => {
if (item.product._id == id) {
item.quantity = item.quantity + num;
}
});
},
async onSubmit() {
const res = await orderAPI({
receiver: "xxx",
regions: "xx省xx市xx县(区)",
address: "xx街道xx号",
orderDetails: this.selectedProduct,
});
console.log(res);
},
async del(id) {
const res = await deleProAPI(id);
console.log(res);
this.getCartData();
},
dels() {},
},
created() {
this.getCartData();
},
mounted() {},
};
标题三、css样式
<style scoped>
.goods {
height: 80px;
display: flex;
padding: 10px;
}
.goods .good_img {
width: 80px;
height: 80px;
margin: 0 8px;
}
.goods .good_img img {
width: 100%;
height: 100%;
}
.goods-r {
display: flex;
flex: 1;
flex-direction: column;
justify-content: space-between;
}
.goods .goods-r h4 {
font-weight: normal;
margin: 0;
line-height: 1;
}
.goods .goods-r .goods-price-num {
display: flex;
justify-content: space-between;
}
.goods .goods-r .goods-price-num .goods-price {
color: red;
}
.goods .goods-r .goods-price-num .goods-num i {
font-style: normal;
}
.goods .goods-r .goods-price-num .goods-num .del {
color: red;
}
</style>