vue3前端开发-小兔鲜-购物车列表单选功能的实现和基础渲染!内容代码比较简单。我们直接看代码就行了。
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
}
//计算属性的使用
const allCount =computed(()=>cartList.value.reduce((a,c)=>a+c.count,0))
const allPrice =computed(()=>cartList.value.reduce((a,c)=>a+c.count*c.price,0))
return{
cartList,
addCart,
delCart,
allCount,
allPrice,
singleCheck
}
},{
//同步存储到缓存中,刷新浏览器就不会丢失数据了
persist: true,
})
这里面,我们新增了一个单选功能的action方法。
到时候会调用,实现(pina的同步设置)
如图所示,我们点击这个,会自动同步到pina里面去。这样就可以实现同步设置的效果了。
<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)
}
</script>
<template>
<div class="xtx-cart-page">
<div class="container m-top-20">
<div class="cart">
<table>
<thead>
<tr>
<th width="120">
<el-checkbox/>
</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">
共 10 件商品,已选择 2 件,商品合计:
<span class="red">¥ 200.00 </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>
需要提醒大家的地方是,我们绑定了是@change回调函数。
这里需要用到两个参数,一个是选择的状态,一个是skuId。