一、功能效果
二、前端代码
购物车的vue代码
<template>
<van-nav-bar left-text="返回" title="购物车" @click-left="onClickLeft">
<template #right>
<van-popover v-model:show="showPopover" placement="bottom-end" :actions="actions" @select="onSelect">
<template #reference>
<van-icon name="more-o" />
</template>
</van-popover>
</template>
</van-nav-bar>
<van-checkbox-group v-model="selectProducts" @change="ckGropChange">
<van-swipe-cell v-for="(item, index) in cartItems" :key="item.id">
<van-row class="box">
<van-col span="2" class="ck"> <van-checkbox :name="item"></van-checkbox></van-col>
<van-col span="22">
<van-card :price="item.price" :desc="item.subName" :title="item.name" :thumb="item.img">
<template #num>
<van-stepper v-model="item.qty" theme="round" button-size="22" @change="computeTotalPrice" />
</template>
</van-card>
</van-col>
</van-row>
<template #right>
<van-button square text="删除" type="danger" class="delete-button" @click="del(item, index)" />
</template>
</van-swipe-cell>
</van-checkbox-group>
<van-submit-bar :price="totalPrice" button-text="提交订单" @submit="onSubmit">
<van-checkbox v-model="checkedAll">全选</van-checkbox>
</van-submit-bar>
</template>
<script setup lang="ts">
import { ref, onMounted, reactive, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { productApi } from '@/api/index'
const selectProducts: any = ref([])
const totalPrice = ref(0)
const showPopover = ref(false)
const checkedAll = ref(false)
const cartItems = ref([
{
id: 1,
productId: 108,
img: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
name: '胜者心法:资治通鉴成事之道',
subName: '胜者心法:这是子标题',
price: "2.00",
qty: 1,
checked: true
},
{
id: 2,
productId: 109,
img: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg',
name: '认知破局 怎样突破能力、视野和思维的局限',
subName: '胜者心法:这是子标题',
price: "3.00",
qty: 2,
checked: false
}
])
const actions = [
{ text: '清空所有', id: 1 },
{ text: '清空所选', id: 2 },
{ text: '选项三' },
];
onMounted(() => {
selectProducts.value = cartItems.value.filter(item => item.checked == true)
if (cartItems.value.length == selectProducts.value.length) {
checkedAll.value = true
}
computeTotalPrice()
})
const onSelect = (action) => {
if (action.id == 1) {
//呼叫清空购物车清空接口
cartItems.value = []
selectProducts.value = []
}
};
const ckGropChange = () => {
computeTotalPrice()
if (cartItems.value.length == selectProducts.value.length) {
checkedAll.value = true
}
if (selectProducts.value.length == 0) {
checkedAll.value = false
}
}
const computeTotalPrice = () => {
let total_Price = 0
selectProducts.value.forEach((item: any) => {
total_Price += item.qty * item.price
});
totalPrice.value = total_Price * 100
}
watch(() => checkedAll.value, (newValue, oldValue) => {
if (newValue) {
selectProducts.value = cartItems.value
} else {
selectProducts.value = []
}
})
const del = (item: any, index: number) => {
//呼叫接口,从用户购物车里面删除这个商品 item.productId
cartItems.value.splice(index, 1)
selectProducts.value = selectProducts.value.filter((it: any) => it.id != item.id)
if (cartItems.value.length == selectProducts.value.length) {
checkedAll.value = true
}
if (selectProducts.value.length == 0) {
checkedAll.value = false
}
}
const onSubmit = () => {
console.log(selectProducts.value);
};
const onClickLeft = () => history.back();
</script>
<style scoped>
.delete-button {
height: 100%;
}
.ck {
display: flex;
justify-content: center;
align-items: center;
}
.box {
border-radius: 15px;
margin: 5px 10px 5px 10px;
background-color: #fff;
}
.van-card {
background-color: #fff;
border-radius: 15px;
}
</style>