代码如下所示:
import { computed, ref } from 'vue'
import { defineStore } from 'pinia'
export const useCartStore =defineStore('cart',()=>{
const cartList = ref([])
const addCart = (goods)=>{
//添加购物车操作
//如果已经添加过了,count++
//没有添加过,直接push
//s思路:通过匹配传递过来的商品对象的中的skuId能不能在cartList中找到,
const item = cartList.value.find((item)=>goods.skuId === item.skuId)
if(item){
//找到了
item.count++
}else{
cartList.value.push(goods)
}
}
// 删除购物车
const delCart = async (skuId) => {
// 思路:
// 1. 找到要删除项的下标值 - splice
// 2. 使用数组的过滤方法 - filter
const idx = cartList.value.findIndex((item) => skuId === item.skuId)
cartList.value.splice(idx, 1)
}
//单选功能
const singleCheck=(skuId,selected)=>{
const item = cartList.value.find((item)=>item.skuId===skuId)
item.selected = selected
}
// 全选功能action
const allCheck = (selected) => {
// 把cartList中的每一项的selected都设置为当前的全选框状态
cartList.value.forEach(item => item.selected = selected)
}
//计算属性的使用
//1.总的数量
const allCount =computed(()=>cartList.value.reduce((a,c)=>a+c.count,0))
//2.总的货款
const allPrice =computed(()=>cartList.value.reduce((a,c)=>a+c.count*c.price,0))
//3.已经勾选的数量
const selectedCount = computed(()=> cartList.value.filter(item => item.selected).reduce((a,c)=>a+c.count,0))
//4.已选择商品的总货款
const selectedPrice = computed(()=> cartList.value.filter(item => item.selected).reduce((a,c)=>a + c.count * c.price,0))
// 是否全选计算属性
const isAll = computed(() => cartList.value.every((item) => item.selected))
return{
cartList,
addCart,
delCart,
allCheck,
allCount,
allPrice,
selectedCount,
selectedPrice,
isAll,
singleCheck
}
},{
//同步存储到缓存中,刷新浏览器就不会丢失数据了
persist: true,
})
这个是store对象里面的增加了2个变量。分别是,当前选择的产品数量,当前勾选的产品的总货款。
如图所示。
<script setup>
import { useCartStore } from '@/stores/cart'
const cartStore = useCartStore()
// 单选回调
const singleCheck = (i, selected) => {
console.log(i, selected)
// store cartList 数组 无法知道要修改谁的选中状态?
// 除了selected补充一个用来筛选的参数 - skuId
cartStore.singleCheck(i.skuId, selected)
}
const allCheck = (selected) => {
cartStore.allCheck(selected)
}
</script>
<template>
<div class="xtx-cart-page">
<div class="container m-top-20">
<div class="cart">
<table>
<thead>
<tr>
<th width="120">
<el-checkbox :model-value="cartStore.isAll" @change="allCheck"/>
</th>
<th width="400">商品信息</th>
<th width="220">单价</th>
<th width="180">数量</th>
<th width="180">小计</th>
<th width="140">操作</th>
</tr>
</thead>
<!-- 商品列表 -->
<tbody>
<tr v-for="i in cartStore.cartList" :key="i.id">
<td>
<!--单选框-->
<el-checkbox :model-value="i.selected" @change="(selected) => singleCheck(i, selected)"/>
</td>
<td>
<div class="goods">
<RouterLink to="/"><img :src="i.picture" alt="" /></RouterLink>
<div>
<p class="name ellipsis">
{{ i.name }}
</p>
</div>
</div>
</td>
<td class="tc">
<p>¥{{ i.price }}</p>
</td>
<td class="tc">
<el-input-number v-model="i.count" />
</td>
<td class="tc">
<p class="f16 red">¥{{ (i.price * i.count).toFixed(2) }}</p>
</td>
<td class="tc">
<p>
<el-popconfirm title="确认删除吗?" confirm-button-text="确认" cancel-button-text="取消" @confirm="delCart(i)">
<template #reference>
<a href="javascript:;">删除</a>
</template>
</el-popconfirm>
</p>
</td>
</tr>
<tr v-if="cartStore.cartList.length === 0">
<td colspan="6">
<div class="cart-none">
<el-empty description="购物车列表为空">
<el-button type="primary">随便逛逛</el-button>
</el-empty>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- 操作栏 -->
<div class="action">
<div class="batch">
共 {{ cartStore.allCount }} 件商品,已选择 {{cartStore.selectedCount}} 件,商品合计:
<span class="red">¥ {{ cartStore.selectedPrice.toFixed(2) }} </span>
</div>
<div class="total">
<el-button size="large" type="primary" >下单结算</el-button>
</div>
</div>
</div>
</div>
</template>
<style scoped lang="scss">
.xtx-cart-page {
margin-top: 20px;
.cart {
background: #fff;
color: #666;
table {
border-spacing: 0;
border-collapse: collapse;
line-height: 24px;
th,
td {
padding: 10px;
border-bottom: 1px solid #f5f5f5;
&:first-child {
text-align: left;
padding-left: 30px;
color: #999;
}
}
th {
font-size: 16px;
font-weight: normal;
line-height: 50px;
}
}
}
.cart-none {
text-align: center;
padding: 120px 0;
background: #fff;
p {
color: #999;
padding: 20px 0;
}
}
.tc {
text-align: center;
a {
color: $xtxColor;
}
.xtx-numbox {
margin: 0 auto;
width: 120px;
}
}
.red {
color: $priceColor;
}
.green {
color: $xtxColor;
}
.f16 {
font-size: 16px;
}
.goods {
display: flex;
align-items: center;
img {
width: 100px;
height: 100px;
}
>div {
width: 280px;
font-size: 16px;
padding-left: 10px;
.attr {
font-size: 14px;
color: #999;
}
}
}
.action {
display: flex;
background: #fff;
margin-top: 20px;
height: 80px;
align-items: center;
font-size: 16px;
justify-content: space-between;
padding: 0 30px;
.xtx-checkbox {
color: #999;
}
.batch {
a {
margin-left: 20px;
}
}
.red {
font-size: 18px;
margin-right: 20px;
font-weight: bold;
}
}
.tit {
color: #666;
font-size: 16px;
font-weight: normal;
line-height: 50px;
}
}
</style>
接下来就是在组件内,调用这个变量的值,做插值运算的调用就行了。
如图所示。这个位置改成了我们刚刚生成的数据信息。
登录用户,验证后操作显示一切正常。
转载请注明:可思数据 » vue3前端开发-小兔鲜超市-本地购物车列表页面的统计计算