本文只是简单的模仿天猫APP的购物车列表的样式效果,并实现了部分事件功能,功能并不完善,请降低期待观看。
天猫APP的购物车效果:
小程序模仿的实现效果:
wxml部分的代码:
<view wx:if="{{!isCartEmpty}}">
<view class="cart-item" wx:for="{{cartList}}" wx:key="{{item.merchantInfo.merchantId}}">
<!-- 商家部分布局 -->
<view class="item-box item-merchant">
<view class="cart-check-box">
<icon class="cart-item-redio" wx:if="{{item.merchantInfo.hasSelected}}" type="success" color="red" data-merchant-id="{{item.merchantInfo.merchantId}}" bind:tap="selectGoodsGroup" />
<icon class="cart-item-redio" wx:else type="circle" color="gray" data-merchant-id="{{item.merchantInfo.merchantId}}" bind:tap="selectGoodsGroup" />
</view>
<view class="merchant-info">
<view bind:tap="goToStoreHome">
<image src="http://n1.itc.cn/img8/wb/smccloud/recom/2015/05/29/143288664727843841.jpeg" mode="aspectFill" />
<text style="font-size: 37rpx;color:#424242; font-weight:bold;">{{item.merchantInfo.name}}<text class="angle"/></text>
</view>
<text style="margin-right:25rpx;font-size:30rpx;" wx:if="{{item.merchantInfo.isActivity}}">领券</text>
</view>
</view>
<!-- 商品列表部分布局 -->
<view class="item-box item-goods" wx:for="{{item.goodsList}}" wx:for-item="goods" wx:key="{{goods.id}}">
<view class="cart-check-box">
<icon class="cart-item-redio" wx:if="{{goods.hasSelected}}" type="success" color="red" data-merchant-id="{{goods.merchantId}}" data-goods-id="{{goods.id}}" bind:tap="selectGoodsSingle" />
<icon class="cart-item-redio" wx:else type="circle" color="gray" data-merchant-id="{{goods.merchantId}}" data-goods-id="{{goods.id}}" bind:tap="selectGoodsSingle" />
</view>
<view class="goods-info">
<view>
<image src="http://img14.360buyimg.com/n1/jfs/t20386/340/2137984030/165902/9dcb0893/5b45c9feN76c521a9.jpg" style="width:200rpx;height:200rpx;border-radius:10rpx;" mode="widthFix"></image>
</view>
<!-- 商品信息部分布局 -->
<view class="goods-info-details">
<view>
<view style="font-size:30rpx;color:#3C3C3C;">{{goods.title}}</view>
<view style="margin-top:10rpx;">
<text class="goods-desc">静音自动摇头上下<text class="down"/></text>
</view>
</view>
<!-- 商品价格、数量布局 -->
<view class="goods-price-quantity">
<view>
<text>¥{{goods.price}}</text>
</view>
<view class="goods-quantity-switch-box">
<view class="goods-quantity-show" bind:tap="showUpdateQuantityDialog" wx:if="{{goods.quantityUpdatable}}">
<view class="goods-quantity-boder goods-quantity-update">
<text class="quantity-minus-box" bindtap="minus" data-merchant-id="{{goods.merchantId}}" data-goods-id="{{goods.id}}" >-</text>
<text class="quantity_update-box">{{goods.quantity}}</text>
<text class="quantity-pluse-box" bindtap="pluse" data-merchant-id="{{goods.merchantId}}" data-goods-id="{{goods.id}}" >+</text>
</view>
<icon style="margin-left:10rpx;" type="cancel" color="red" data-merchant-id="{{goods.merchantId}}" data-goods-id="{{goods.id}}" bind:tap="hideUpdateQuantity" />
</view>
<text wx:else class="goods-quantity-boder goods-quantity" bind:tap="showUpdateQuantity" data-merchant-id="{{goods.merchantId}}" data-goods-id="{{goods.id}}">×{{goods.quantity}}</text>
</view>
</view>
</view>
</view>
</view>
</view>
<view style="height:120rpx"></view>
<view class="cart-footer">
<view style="height:1rpx;background-color:#f5f5f5"></view>
<view class="cart-footer-box">
<view>
<icon wx:if="{{hasAllSelected}}" type="success" color="red" class="total-select" bindtap="selectAll" />
<icon wx:else type="circle" color="gray" class="total-select" bindtap="selectAll" />
</view>
<view>
<text class="total-text">合计:<text class="cart-toatl-price">¥{{totalPrice}}</text></text>
<text class="settlement-text" bind:tap="goToOrderSubmit">结算</text>
</view>
</view>
</view>
</view>
<block wx:else>
<view class="catnone">
<image src="../../assets/images/cart_none_a.png" mode="widthFix"></image>
<view class="catnone-text">您的购物车还是空的,快去买买买吧!</view>
</view>
<view class="cart-recommend">
<block wx:for="{{recommends}}" wx:key="index">
<view class="recommend-item">
<image class="item-img" src="{{item.image}}" mode="widthFix"></image>
<view class="item-text">{{item.text}}</view>
<view class="item-price">{{item.price}}</view>
</view>
</block>
</view>
</block>
wxss部分代码:
/* pages/shoppingcart/shoppingcart.wxss */
.title_edit {
margin-left: 20rpx;
float: left;
position: absolute;
left: 0px;
}
.title {
width: 100%;
height: 88rpx;
display: flex;
align-items: center;
justify-content: center;
border-bottom: 2rpx solid gray;
}
.catnone {
text-align: center;
padding-top: 20rpx;
}
.catnone image {
display: block;
margin: auto;
}
.catnone-text {
margin-top: 20rpx;
color: lightgrey;
}
.cart-recommend {
width: 100%;
display: flex;
margin-top: 40rpx;
justify-content: space-evenly;
}
.item-img {
width: 200rpx;
height: 200rpx;
}
.cart-footer {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
height: 110rpx;
line-height: 90rpx;
box-sizing: border-box;
}
.cart-footer-box {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
height: 100%;
box-sizing: border-box;
background-color: #fff;
}
.settlement-text {
border-radius: 85rpx;
background-color: #f40;
font-size: 35rpx;
text-align: center;
margin-left: 15rpx;
margin-right: 15rpx;
padding-top: 20rpx;
padding-bottom: 20rpx;
padding-right: 55rpx;
padding-left: 55rpx;
color: #fff;
}
.cart-toatl-price {
height: 100%;
font-size: 30rpx;
color: #f40;
}
.total-text {
height: 100%;
font-size: 33rpx;
color: #333;
}
.total-select {
position: absolute;
left: 20rpx;
top: 25rpx;
width: 45rpx;
height: 45rpx;
}
.container {
display: flex;
flex-direction: column;
}
.cart-item {
margin-left: 15rpx;
margin-right: 15rpx;
background-color: #fff;
border-radius: 10px;
box-shadow: 0px 0px 3px 0px rgba(183, 183, 183, 0.8);
box-sizing: border-box;
margin-top: 25rpx;
padding-bottom: 25rpx;
}
.cart-item-redio {
margin-left: 20rpx;
margin-right: 20rpx;
align-self: center;
width: 45rpx;
height: 45rpx;
}
.check-box {
position: relative;
z-index: 1;
float: left;
width: 45rpx;
height: 45rpx;
background-position: 0 0;
line-height: 200em;
overflow: hidden;
cursor: pointer;
}
.item-box {
display: flex;
padding-left: 15rpx;
align-items: center;
}
.item-merchant {
line-height: 80rpx;
}
.merchant-info {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
width: 100%;
}
.merchant-info view {
display: flex;
align-items: center;
}
.merchant-info image {
margin-left: 15rpx;
width: 55rpx;
height: 55rpx;
border-radius: 10rpx
}
.merchant-info text {
font-size: 35rpx;
color: #333;
margin-left: 25rpx;
}
.cart-check-box {
display: flex;
/* opacity: 0.5; */
/* 透明度 */
}
.cart-check-box .cart-pro-select {
justify-content: center;
align-content: center;
}
.item-goods {
margin-top: 30rpx;
height: 200rpx;
}
.goods-info {
display: flex;
height: 200rpx;
width: 100%;
align-items: center;
}
.goods-info-details {
display: flex;
flex-direction: column;
height: 100%;
width: 100%;
margin-right: 20rpx;
margin-left: 20rpx;
justify-content: space-between;
}
.goods-desc {
font-size: 27rpx;
padding-right: 17rpx;
padding-left: 17rpx;
padding-top: 12rpx;
padding-bottom: 12rpx;
background-color: #f5f5f5;
color: #666;
border-radius: 15rpx
}
.goods-quantity-box {
display: flex;
align-content: space-around;
border-width: 1rpx;
border-style: solid;
color: #e5e5e5;
}
.goods-price-quantity {
display: flex;
justify-content: space-between;
/* align-items: flex-end; */
}
.goods-quantity-switch-box {
display: flex;
justify-content: flex-end;
}
.goods-quantity-boder {
border-radius: 17rpx;
border-width: 1rpx;
border-style: solid;
border-color: #e5e5e5;
}
.goods-quantity {
/* position: absolute; */
font-size: 27rpx;
padding-right: 12rpx;
padding-left: 12rpx;
padding-top: 8rpx;
padding-bottom: 8rpx;
text-align: center;
}
.goods-quantity-show {
display: flex;
align-items: center;
position: absolute;
}
.goods-quantity-update {
display: flex;
align-items: center;
width: 160rpx;
justify-content: space-around;
}
.quantity-minus-box {
padding-right: 12rpx;
padding-left: 12rpx;
text-align: center;
}
.quantity_update-box {
border-right: 1rpx solid #e5e5e5;
border-left: 1rpx solid #e5e5e5;
font-size: 27rpx;
text-align: center;
flex-grow: 1.7;
}
.quantity-pluse-box {
padding-right: 12rpx;
padding-left: 12rpx;
text-align: center;
}
.angle {
display: inline-block;
transform: rotate(45deg);
height: 18rpx;
width: 18rpx;
border-width: 1rpx 1rpx 0 0;
border-style: solid;
margin-left: 0.1em;
}
.down {
display: inline-block;
transform: rotate(135deg);
height: 12rpx;
width: 12rpx;
border-width: 3rpx 3rpx 0 0;
border-style: solid;
align-self: flex-start;
position: relative;
margin-left: 0.4em;
margin-bottom: 8rpx;
}
.cart-list {
position: relative;
padding: 20rpx 20rpx 20rpx 285rpx;
height: 185rpx;
border-bottom: 1rpx solid #e9e9e9;
}
js部分代码:
// pages/shoppingcart/shoppingcart.js
const app = getApp()
Page({
/**
* 页面的初始数据
*/
data: {
statusBarHeight: app.globalData.statusBarHeight,
isCartEmpty: false, // 购物车是否有商品
hasAllSelected: false, // 是否全选
cartList: [{
merchantInfo: {
merchantId: "111",
name: "这是我家的小小小店",
icon: '/assets/images/cart_none_a.png',
hasSelected: false,
isActivity: true
},
goodsList: [{
id: 1111,
merchantId: "111",
title: '格力迷你静音台式电风扇',
image: '/assets/images/cart_none_a.png',
quantity: 4,
price: 100,
quantityUpdatable: false,
hasSelected: false
}]
},
{
"merchantInfo": {
"merchantId": "222",
"name": "这是我家的小小小店",
"icon": '/assets/images/cart_none_a.png',
"hasSelected": false,
"quantityUpdatable": false,
"isActivity": false
},
"goodsList": [{
"id": 2221,
"merchantId": "222",
"title": '格力迷你静音台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 4,
"price": 130,
"quantityUpdatable": false,
"hasSelected": false
},
{
"id": 22222,
"merchantId": "222",
"title": '格力家用台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 1,
"price": 320,
"quantityUpdatable": false,
"hasSelected": false
}
]
},
{
"merchantInfo": {
"merchantId": "333",
"name": "这是我家的小小小店",
"icon": '/assets/images/cart_none_a.png',
"hasSelected": false,
"isActivity": true
},
"goodsList": [{
"id": 3331,
"merchantId": "333",
"title": '格力迷你静音台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 4,
"price": 110,
"quantityUpdatable": false,
"hasSelected": false
},
{
"id": 3332,
"merchantId": "333",
"title": '格力家用台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 1,
"price": 310,
"quantityUpdatable": false,
"hasSelected": false
},
{
"id": 3333,
"merchantId": "333",
"title": '格力迷你静音台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 4,
"price": 120,
"quantityUpdatable": false,
"hasSelected": false
}
]
},
{
"merchantInfo": {
"merchantId": "444",
"name": "这是我家的小小小店",
"icon": '/assets/images/cart_none_a.png',
"hasSelected": false,
"isActivity": false
},
"goodsList": [{
"id": 4441,
"merchantId": "444",
"title": '格力迷你静音台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 4,
"price": 130,
"quantityUpdatable": false,
"hasSelected": false
},
{
"id": 4442,
"merchantId": "444",
"title": '格力家用台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 1,
"price": 290,
"quantityUpdatable": false,
"hasSelected": false
},
{
"id": 4443,
"merchantId": "444",
"title": '格力迷你静音台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 4,
"price": 150,
"quantityUpdatable": false,
"hasSelected": false
},
{
"id": 4444,
"merchantId": "444",
"title": '格力家用台式电风扇',
"image": '/assets/images/cart_none_a.png',
"quantity": 1,
"price": 280,
"quantityUpdatable": false,
"hasSelected": false
}
]
}
],
totalPrice: 0,
recommends: [{
image: "https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1281982941,672088714&fm=26&gp=0.jpg",
text: "哈哈哈哈哈",
price: "¥59.99"
},
{
image: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593543702366&di=6e0d404920b3480730ffa7841d1a3e31&imgtype=0&src=http%3A%2F%2Fwww.szthks.com%2Flocalimg%2F687474703a2f2f6777312e616c6963646e2e636f6d2f62616f2f75706c6f616465642f69382f5431504858625843786958585858585858585f2121302d6974656d5f7069632e6a7067.jpg",
text: "呵呵呵呵",
price: "¥10.99"
},
{
image: "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1593544013692&di=82cbdcbb7ba6b5e29edbe930d828b6cb&imgtype=0&src=http%3A%2F%2Fimg3.imgtn.bdimg.com%2Fit%2Fu%3D1156539113%2C3136930104%26fm%3D214%26gp%3D0.jpg",
text: "嘿嘿嘿",
price: "¥88.88"
}
]
},
/**
* 由商家列表项选择商品组事件
*/
selectGoodsGroup(e) {
console.log(e);
let cartList = this.data.cartList;
const merchantId = e.currentTarget.dataset.merchantId;
cartList.forEach(function (item) {
if (item.merchantInfo.merchantId === merchantId) {
const hasSelected = item.merchantInfo.hasSelected;
item.merchantInfo.hasSelected = !hasSelected;
item.goodsList.forEach(function (goods) {
goods.hasSelected = item.merchantInfo.hasSelected;
})
return;
};
})
this.setData({
cartList: cartList,
})
this.calculateTotalPrice();
this.verifyHasAllSelected();
},
/**
* 计算商品总价格事件
*/
calculateTotalPrice() {
let cartList = this.data.cartList;
let totalPrice = 0;
cartList.forEach(function (item) {
item.goodsList.forEach(function (goods) {
// console.log(goods);
if (goods.hasSelected) {
totalPrice += goods.price * goods.quantity;
}
// console.log(totalPrice);
})
})
this.setData({
totalPrice: totalPrice
})
},
/**
* 验证是否全选事件
*/
verifyHasAllSelected() {
let hasAllSelected = true;
let cartList = this.data.cartList;
cartList.forEach(function (item) {
if (!item.merchantInfo.hasSelected) {
hasAllSelected = false;
return;
}
item.goodsList.forEach(function (goods) {
if (!goods.hasSelected) {
hasAllSelected = false;
return;
}
})
})
console.log(hasAllSelected);
this.setData({
hasAllSelected: hasAllSelected,
})
},
/**
* 单个商品选择事件
*/
selectGoodsSingle(e) {
console.log(e);
let cartList = this.data.cartList;
const merchantId = e.currentTarget.dataset.merchantId;
const goodsId = e.currentTarget.dataset.goodsId;
cartList.forEach(function (item) {
if (item.merchantInfo.merchantId === merchantId) {
item.goodsList.forEach(function (goods) {
if (goods.id === goodsId) {
const hasSelected = goods.hasSelected;
goods.hasSelected = !hasSelected;
return;
}
})
return;
}
});
this.setData({
cartList: cartList,
})
this.calculateTotalPrice();
this.verifyHasAllSelected();
},
/**
* 商品数量减1事件
*/
minus(e) {
console.log(e);
let cartList = this.data.cartList;
const merchantId = e.currentTarget.dataset.merchantId;
const goodsId = e.currentTarget.dataset.goodsId;
let hasSelected;
cartList.forEach(function (item) {
if (item.merchantInfo.merchantId === merchantId) {
item.goodsList.forEach(function (goods) {
if (goods.id === goodsId) {
if (goods.quantity <= 1) {
wx.showToast({
title: '商品数量少于1',
})
} else {
goods.quantity -= 1;
}
hasSelected = goods.hasSelected;
return;
}
})
return;
}
});
this.setData({
cartList: cartList,
})
if (hasSelected) {
this.calculateTotalPrice();
}
},
/**
* 商品数量加1事件
*/
pluse(e) {
console.log(e);
let cartList = this.data.cartList;
const merchantId = e.currentTarget.dataset.merchantId;
const goodsId = e.currentTarget.dataset.goodsId;
let hasSelected;
cartList.forEach(function (item) {
if (item.merchantInfo.merchantId === merchantId) {
item.goodsList.forEach(function (goods) {
if (goods.id === goodsId) {
if (goods.quantity >= 10) {
wx.showToast({
title: '数量超过10',
})
} else {
goods.quantity += 1;
}
hasSelected = goods.hasSelected;
return;
}
})
return;
}
});
this.setData({
cartList: cartList,
})
if (hasSelected) {
this.calculateTotalPrice();
}
},
/**
* 购物车全选事件
*/
selectAll(e) {
let hasAllSelected = this.data.hasAllSelected;
hasAllSelected = !hasAllSelected;
let cartList = this.data.cartList;
for (let i = 0; i < cartList.length; i++) {
let item = cartList[i];
item.hasSelected = hasAllSelected;
item.merchantInfo.hasSelected = hasAllSelected;
let goodsList = item.goodsList;
for (let i = 0; i < goodsList.length; i++) {
let goodsItem = goodsList[i];
goodsItem.hasSelected = hasAllSelected;
}
}
this.setData({
hasAllSelected: hasAllSelected,
cartList: cartList
});
this.calculateTotalPrice();
},
/**
* 显示修改单个商品数量布局事件
*/
showUpdateQuantity(e) {
console.log(e);
const merchantId = e.currentTarget.dataset.merchantId;
const goodsId = e.currentTarget.dataset.goodsId;
this.showOrHideUpdateQuantity(merchantId, goodsId, true);
},
/**
* 隐藏修改单个商品数量事件
*/
hideUpdateQuantity(e) {
console.log(e);
const merchantId = e.currentTarget.dataset.merchantId;
const goodsId = e.currentTarget.dataset.goodsId;
this.showOrHideUpdateQuantity(merchantId, goodsId, false);
},
/**
* 显示改商品数量对话框事件
*/
showUpdateQuantityDialog() {
},
/**
* 显示或者隐藏修改商品数量布局事件
*/
showOrHideUpdateQuantity(merchantId, goodsId, quantityUpdatable) {
let cartList = this.data.cartList;
console.log(merchantId);
cartList.forEach(function (item) {
if (item.merchantInfo.merchantId === merchantId) {
item.goodsList.forEach(function (goods) {
if (goods.id === goodsId) {
goods.quantityUpdatable = quantityUpdatable;
return;
}
})
return;
}
});
this.setData({
cartList: cartList,
})
}
})
由于作者水平有限,语言描述及代码实现中难免有纰漏,望各位看官多提宝贵意见!
Hello , World !
感谢所有!