微信小程序实现一个购物车页面的简易列表效果

 本文只是简单的模仿天猫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 !

感谢所有!

  • 14
    点赞
  • 69
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

windfallsheng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值