看图描述
可以得到我们实现的购物功能满足 全选、反选,明细选中,明细全选和反选,computed 计算属性 和 总价钱,选中件数等等操作(里面有watch 监听示例,但是不建议用,因为watch 监听太耗用性能,computed 足可以满足我们的需求了)
上代码。
<template>
<div class="shopCart">
<div v-if="dataSource.length > 0">
<a-row class="shopHead">
<a-col :span="2">
<a-checkbox v-model:checked="allChecked" @change="checkAll">
全选
</a-checkbox>
</a-col>
<a-col :span="6" class="colSpan">商品</a-col>
<a-col :span="4" class="colSpan">单价</a-col>
<a-col :span="4" class="colSpan">数量</a-col>
<a-col :span="4" class="colSpan">小计</a-col>
<a-col :span="4" class="colSpan">操作</a-col>
</a-row>
<a-row v-for="item in dataSource" :key="item.id" class="shopMessage">
<a-col :span="24" class="company">
<a-checkbox
v-model:checked="item.check"
@click="selectShopItems(item)"
>
{{ item.comName }}
</a-checkbox>
</a-col>
<a-col v-for="el in item.shopList" :key="el.ids" :span="24">
<a-row>
<a-col :span="1" class="checkboxStyle">
<a-checkbox
v-model:checked="el.itemCheck"
@click="checkItem(el, item)"
/>
</a-col>
<a-col :span="7" class="shopMsg">
<img :src="el.url" class="imgStyle" />
<div class="ShopDiv">
<p :title="el.shopName">{{ el.shopName }}</p>
<p>
<span class="pSpan">款式:{{ el.type }}</span>
<span class="pSpan">颜色{{ el.color }}</span>
</p>
</div>
</a-col>
<a-col :span="4" class="itemCol">
<span>{{ el.price }}</span>
</a-col>
<a-col :span="4" class="itemCol">
<div>
<a-button @click="changeProductCount(el, 'sub')"> - </a-button>
<a-input-number v-model:value="el.num" :controls="false" />
<a-button @click="changeProductCount(el, 'add')"> + </a-button>
</div>
</a-col>
<a-col :span="4" class="itemCol" style="color: #f51d29">
<!-- ¥ <span>{{ el.price * el.num }}</span> -->
¥ <span>{{ el.total }}</span>
</a-col>
<a-col :span="4" class="itemCol">
<a-button type="text" @click="handRemove(el, el.ids)">
删除
</a-button>
</a-col>
</a-row>
</a-col>
</a-row>
<a-row class="shopFooter">
<a-col :span="2">
<a-checkbox v-model:checked="allChecked" @change="checkAll">
全选
</a-checkbox>
</a-col>
<a-col :span="3" class="colSpan"> 已选择 {{ checkNum }} 件 </a-col>
<a-col :span="3" class="colSpan" @click="removeAll()">删除选中</a-col>
<a-col :span="2" />
<a-col :span="2" />
<a-col :span="4" />
<a-col :span="4" class="colSpan">
总价(不含邮费): {{ priceTotal }}
</a-col>
<a-col :span="4" class="colSpan">
<a-button> 继续购物 </a-button>
<a-button type="primary" danger @click="settleAccount">
去结算
</a-button>
</a-col>
</a-row>
</div>
<div v-else>
咋内数据
<!-- <a-empty :image="simpleImage" /> -->
</div>
</div>
</template>
<script>
import {
defineComponent,
reactive,
onMounted,
computed,
ref,
watch,
} from "vue";
import { getSearchList } from "./service";
import { useRoute, useRouter } from "vue-router";
import { PlusOutlined, MinusOutlined } from "@ant-design/icons-vue";
export default defineComponent({
setup() {
let shopCart = reactive({
dataSource: [
{
comName: "台州电动车公司",
id: "1",
check: false,
shopList: [
{
shopName:
"立马电动车新款IN趣电动摩托车外卖长跑王电瓶车双碟刹长续航通勤代步车 极光烟灰-72V20A",
url: "xxxxxxxxxxxxx",
type: "aaa",
color: "bbb",
price: 10,
num: 1,
total: 10,
itemCheck: false,
ids: "1-1",
},
{
shopName:
"立马电动车新款IN趣电动摩托车外卖长跑王电瓶车双碟刹长续航通勤代步车 极光烟灰-72V20A",
url: "xxxxxxxxxxxxx",
type: "aaa",
color: "bbb",
price: 10,
num: 1,
total: 10,
itemCheck: false,
ids: "1-2",
},
],
},
{
comName: "广州电动车公司",
id: "2",
check: false,
shopList: [
{
shopName: "商品2",
url: "xxxxxxxxxxxxx",
type: "aaa",
color: "bbb",
price: 10,
num: 1,
total: 10,
itemCheck: false,
ids: "2-1",
},
],
},
],
});
let allChecked = ref(false);
// let selectId = ref(0); // 选中的数据列表
// 明细数量变更
const changeProductCount = (item, type) => {
if (type === "sub" && item.num > 1) {
item.num--;
item.total = item.price * item.num;
}
if (type === "add") {
item.num++;
item.total = item.price * item.num;
}
};
// 计算总价
let priceTotal = computed(() => {
let totalNum = 0;
shopCart.dataSource.forEach((item) => {
if (item.shopList.length > 0) {
item.shopList.forEach((el) => {
if (el.itemCheck) {
totalNum += el.num * el.price;
}
});
}
});
return totalNum;
});
// 判断选中的件数 和
let checkNum = computed(() => {
let checkNumber = 0;
shopCart.dataSource.forEach((item) => {
if (item.shopList && item.shopList.length > 0) {
item.shopList.forEach((el) => {
if (el.itemCheck) {
checkNumber += 1;
}
});
}
});
return checkNumber;
});
// 公司选中的时候改变明细选中状态
const selectShopItems = (item) => {
console.log(item);
item.check = !item.check;
item.shopList.forEach((p) => {
p.itemCheck = item.check;
});
selectAll();
};
// 明细选中
const checkItem = (el, item) => {
console.log(el, "每一项 el.itemCheck", item.shopList);
el.itemCheck = !el.itemCheck;
let checkCompany = item.shopList.every((s) => s.itemCheck === true);
console.log(checkCompany);
item.check = checkCompany;
selectAll();
};
// 选中公司名称判断全选按钮是否选中
const selectAll = () => {
let checkAll = shopCart.dataSource.every((item) => item.check === true);
allChecked.value = checkAll;
};
// 全选
const checkAll = () => {
console.log(allChecked.value, "allChecked");
if (allChecked.value) {
// console.log(allChecked.value, "全选");
shopCart.dataSource.forEach((item) => {
item.check = true;
item.shopList.forEach((p) => {
p.itemCheck = true;
});
});
} else {
// console.log(allChecked.value, "取消全选");
shopCart.dataSource.forEach((item) => {
item.check = false;
item.shopList.forEach((p) => {
p.itemCheck = false;
});
});
}
};
// 删除明细行
const handRemove = (item, ids) => {
console.log(item, ids, "190");
};
// 删除全部
const removeAll = () => {
// shopCart.dataSource.splice(0, shopCart.dataSource.length);
};
// 去结算
const route = useRoute();
const router = useRouter();
const settleAccount = () => {
// router.push("/settleAccount");
router.push({
path: "/settleAccount",
query: {},
});
};
const searchCartList = async () => {
let res = await getSearchList();
console.log(res, " 获取购物车数据");
};
onMounted(() => {
searchCartList();
});
// // 监听选中的数量 不建议使用
// watch(
// () => shopCart.dataSource,
// (val) => {
// console.log("找到dataSource了", val);
// if (val) {
// selectId.value = 0;
// val.forEach((el) => {
// console.log(el, "每一项变化计算总价");
// el.shopList?.forEach((itemEl) => {
// if (itemEl.itemCheck) {
// selectId.value = selectId.value + 1;
// }
// console.log(selectId.value, "SelectIdSelectIdSelectId");
// });
// });
// }
// },
// { deep: true }
// );
return {
...shopCart,
allChecked,
priceTotal,
// selectId,
checkNum,
changeProductCount,
selectShopItems,
checkAll,
handRemove,
removeAll,
checkItem,
settleAccount,
};
},
});
</script>
<style lang="scss" scoped>
p{
margin: 0;
padding: 0;
}
.shopCart{
padding-top: 30px ;
width: 1200px;
margin: 0 auto;
height: calc(100% - 30px);
.shopHead{
height: 40px;
background: #F8F8F8;
line-height: 40px;
padding: 0 20px;
.colSpan{
text-align: center;
}
}
.cloudt-layout-row{
row-gap: 0px;
margin: 10px 0;
}
.shopMessage{
padding: 0 20px;
}
.checkboxStyle{
display: flex;
align-items: center;
}
.company{
line-height: 60px;
}
.shopMsg{
display: flex;
width: 80px;
height: 80px;
}
.imgStyle{
// width: 50px;
// height: 50px;
width: 80px;
height: 80px;
object-fit: contain;
}
.ShopDiv{
width: calc(100% - 100px);
margin-left: 20px;
.pSpan{
font-size: 12px;
color: #999999;
line-height: 20px;
font-weight: 400;
padding: 5px;
}
}
.itemCol{
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
line-height: 20px;
font-weight: 600;
}
.shopFooter{
height: 40px;
background: #F8F8F8;
line-height: 40px;
padding: 0px 20px;
margin-top:10px;
.colSpan{
text-align: center;
}
}
}
</style>