微信小程序之购物车 —— 微信小程序实战商城系列(5)

续上一篇的文章:微信小程序之商品属性分类 —— 微信小程序实战商城系列(4)

自从认识某人后,我收获了两个成功。登录成功、付款成功,而且还拥有了自己的一辆车:

购物车

也发现了自己的不足之处:

余额不足。

为大家介绍的就是购物车

这里演示从商品列表中添加到购物车

下面先做商品列表页。如下图:

布局分析:

首先一个list的主盒子,接着是item盒子,这是必须的。
      然后把item分成左侧的图片部分,和右侧的说明部分(item盒子使用横向弹性盒)
            右侧的说明部分又分上下2部分(右侧说明部分盒子使用纵向弹性盒)
                  下面价钱购物车部分(下面价钱购物车部分也使用横向弹性盒,中间使用justify-content: space-between;填充空白)

index.wxml:

<!--主盒子-->
<view class="container">
  <!--head-->
  <view class="tit">
    <view class="title_val">商品列表</view>
    <view class="more">更多</view>
  </view>
  <!--list-->
  <view class="goodslist">
    <!--item-->
    <block wx:for="{{goodslist}}">
      <view class="goods">
        <!--左侧图片盒子-->
        <view>
          <image src="{{item.imgUrl}}" class="good-img" />
        </view>
        <!--右侧说明部分-->
        <view class="good-cont">
          <!--上--文字说明-->
          <view class="goods-navigator">
            <text class="good-name">{{item.name}}</text>
          </view>
          <!--下--价格部分-->
          <view class="good-price">
            <text>¥{{item.price}}</text>
            <image id="{{item.id}}" class="cart" src="/images/new_73.jpg" bindtap="addcart" />
          </view>
        </view>
      </view>
    </block>
  </view>
</view>

index.wxss:

/**index.wxss**/
page{
    height: 100%;
}
.container{
    background: #f5f5f5;
}
 
.tit{
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    height: 30px;
    position: relative;
}
.tit::before{
    content:'';
    background: #ffcc00;
    width:5px;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
}
 
.title_val{
    padding: 0 15px;
    font-size: 14px;
    color: #555;
    line-height: 30px;
}
.more{
    font-size: 12px;
    line-height: 30px;
    color: #999;
    padding: 0 5px 0 0 ;
}
.goodslist{
    background: #fff;
    display: flex;
    flex-direction: column;
}
.goods{
    display: flex;
    flex-direction: row;
    border-bottom: 1px solid #ddd;
}
.good-img{
    padding: 5px;
    width: 80px;
    height: 80px;
}
.good-cont{
    display: flex;
    flex: 1;
    flex-direction: column;
    font-size: 14px;
}
.goods-navigator{
    display: flex;
    flex: 1;
    flex-direction: column;
    justify-content: center;
}
.good-name{
    display: flex;
    flex: 1;
    flex-direction: column;
    color: #555;
    justify-content: center;
}
.good-price{
    display: flex;
    flex: 1;
    flex-direction: row;
    justify-content: space-between;
    color:#e4393c;
    font-weight: 600;
}
.cart{
    width: 40px;
    height: 40px;
    padding-right: 10px;
}

index.js:

数据部分,一般情况都是访问接口获取数据的,这里并没有使用网络访问,为了简化demo,直接把一组数据放在data对象中。同学们可以根据其数据结构自己编写后台接口

Page({
    data: {
        goodslist: [
            {
                id:"001",
                imgUrl:"http://img5.imgtn.bdimg.com/it/u=2906541843,1492984080&fm=23&gp=0.jpg",
                name:"女装T恤中长款大码摆裙春夏新款",
                price:"65.00"
            },
            {
                id:"002",
                imgUrl:"http://img4.imgtn.bdimg.com/it/u=1004404590,1607956492&fm=23&gp=0.jpg",
                name:"火亮春秋季 男青年修身款圆领男士T恤",
                price:"68.00"
            },
            {
                id:"003",
                imgUrl:"http://img1.imgtn.bdimg.com/it/u=2305064940,3470659889&fm=23&gp=0.jpg",
                name:"新款立体挂脖t恤女短袖大码宽松条纹V领上衣显瘦休闲春夏",
                price:"86.00"
            },
            {
                id:"004",
                imgUrl:"http://img4.imgtn.bdimg.com/it/u=3986819380,1610061022&fm=23&gp=0.jpg",
                name:"男运动上衣春季上新品 上衣流行装青年",
                price:"119.00"
            },
            {
                id:"005",
                imgUrl:"http://img1.imgtn.bdimg.com/it/u=3583238552,3525141111&fm=23&gp=0.jpg",
                name:"时尚字母三角露胸t恤女装亮丝大码宽松不规则春夏潮",
                price:"69.00"
            },
            {
                id:"006",
                imgUrl:"http://img2.imgtn.bdimg.com/it/u=1167272381,3361826143&fm=23&gp=0.jpg",
                name:"新款立体挂脖t恤短袖大码宽松条纹V领上衣显瘦休闲春夏",
                price:"86.00"
            },
            {
                id:"007",
                imgUrl:"http://img0.imgtn.bdimg.com/it/u=789486313,2033571593&fm=23&gp=0.jpg",
                name:"时尚字母三角露胸t恤女装亮丝大码宽松不规则春夏潮",
                price:"119.00"
            },
            {
                id:"008",
                imgUrl:"http://img2.imgtn.bdimg.com/it/u=3314044863,3966877419&fm=23&gp=0.jpg",
                name:"男运动上衣春季上新品 上衣流行装青年",
                price:"69.00"
            },
        ]
    },
    // 加入购物车
    addcart:function(e){
        this.setData({
            toastHidden:false
        });
        // 遍历列表 与 购物车列表
        for (var i in this.data.goodslist){
            // 列表中某一项item的id == 点击事件传递过来的id。则是被点击的项
            if(this.data.goodslist[i].id == e.target.id){
                // 给goodsList数组的当前项添加count元素,值为1,用于记录添加到购物车的数量
                this.data.goodslist[i].count = 1;
                // 获取购物车的缓存数组(没有数据,则赋予一个空数组)
                var arr = wx.getStorageSync('cart') || [];
                // 如果购物车有数据
                if(arr.length>0){
                    // 遍历购物车数组
                    for(var j in arr){
                        // 判断购物车内的item的id,和事件传递过来的id,是否相等
                        if(arr[j].id == e.target.id){
                            // 相等的话,给count+1(即再次添加入购物车,数量+1)
                            arr[j].count = arr[j].count + 1;
                            // 最后,把购物车数据,存放入缓存(此处不用再给购物车数组push元素进去,因为这个是购物车有的,直接更新当前数组即可)
                            try {
                                wx.setStorageSync('cart', arr)
                            } catch (e) {
                                console.log(e)
                            }
                            // 返回(在if内使用return,跳出循环节约运算,节约性能)
                            return;
                        }
                    }
                    // 遍历完购物车后,没有对应的item项,把goodslist的当前项放入购物车数组
                    arr.push(this.data.goodslist[i]);
                }
                // 购物车没有数据,把item项push放入当前数据(第一次存放时)
                else{
                    arr.push(this.data.goodslist[i]);
                }
                // 最后,把购物车数据,存放入缓存
                try {
                    wx.setStorageSync('cart', arr)
                    // 返回(在if内使用return,跳出循环节约运算,节约性能)
                    return;
                } catch (e) {
                    console.log(e)
                }
            }
        }
    }
})

编写购物车部分,如下图所示:

布局分析:

首先一个list的主盒子,接着是item盒子,这是必须的。

然后把item分成左侧的图片部分,和右侧的说明部分(item盒子使用横向弹性盒)

右侧的说明部分又分上下2部分(右侧说明部分盒子使用纵向弹性盒)

下面价钱、购物加减、购物车部分(使用纵向弹性盒)

最下面的购物加减、购物车部分(使用横向弹性盒,中间使用justify-content: space-between;填充空白)

cart.wxml:

<!--要是够车内没有数据,就行显示没有数据-->
<view class="cart" hidden="{{iscart}}">
    <image src="/images/cart.png"/>
    <view>购物车什么都没有,赶快去购物吧</view>
</view>
<!--要是有数据,就显示数据-->
<view class="cartList" hidden="{{!iscart}}">
    <!--header-->
    <view class="baoyou"></view>
    <!--list item-->
    <block wx:for="{{cart}}">
        <view class="goods">
            <!--左侧图片-->
            <view>
                <image src="{{item.imgUrl}}" class="good-img"/>
            </view>
            <!--右侧说明部分-->
            <view class="good-cont">
                <!--文字说明-->
                <view class="goods-navigator">
                    <text class="good-name">{{item.name}}</text>
                </view>
                <!--价钱和购物加减的父盒子-->
                <view class="good-price">
                    <text class="price">¥{{item.price}}</text>
                    <view class="btn-box">
                        <view class="btn">
                            <button id="del{{index}}" type="default" size="mini" bindtap="delCount">-</button>
                            <input  value="{{item.count}}"/>
                            <button id="add{{index}}" type="default" size="mini" bindtap="addCount">+</button>
                        </view>
                        <image id="img{{index}}" src="/images/del2.png" bindtap="delGoods"/>
                    </view>
                </view>
            </view>
        </view>
    </block>
    <!--footer-->
    <view class="total">
        <view class="total_text">合计:<text>¥{{total}}</text></view>
        <button class="total_js" size="mini">去结算({{goodsCount}})</button>
    </view>
</view>

cart.wxss:

page {
  background: #f2ebe3;
}
 
.cart {
  padding: 100px 0 0 0;
  display: flex;
  justify-content: center;
  flex-direction: column;
  align-items: center;
  color: #999;
}
 
.cart image {
  width: 66px;
  height: 66px;
  margin-bottom: 20px;
}
 
.baoyou {
  font-size: 18px;
  color: #db2929;
  padding: 10px;
}
 
.goods {
  background: #fff;
  border-top: 1px solid #ddd;
  margin-bottom: 10px;
  padding: 10px 10px 0 10px;
  display: flex;
}
 
.goods image {
  width: 80px;
  height: 80px;
  border: 1px solid #ddd;
}
 
.goods .good-cont {
  display: flex;
  flex: 1;
  flex-direction: column;
  color: #555;
  font-size: 14px;
  padding: 5px;
  height: 100px;
}
 
.goods .good-cont .goods-navigator {
  display: flex;
  flex: 2;
}
 
.goods .good-cont .good-price {
  display: flex;
  flex-direction: column;
  flex: 3;
}
 
.goods .good-cont .good-price .price {
  font-size: 16px;
  color: #ec5151;
}
 
.goods .good-cont .good-price .btn-box {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
}
 
.goods .good-cont .good-price .btn-box image {
  width: 23px;
  height: 23px;
  border: 0;
  margin: 0;
}
 
.goods .good-cont .good-price .btn {
  display: flex;
  flex-direction: row;
}
 
.goods .good-cont .good-price .btn input {
  margin: 0;
  width: 40px;
  text-align: center;
  border: 1px solid #eee;
  font-size: 16px;
  height: 28px;
}
 
.goods .good-cont .good-price .btn button {
  margin: 0;
}
 
.total {
  height: 40px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  padding: 0 20px;
}
 
.total .total_text {
  display: flex;
  color: #777;
}
 
.total .total_text text {
  color: #ec5151;
}
 
.total .total_js {
  color: #fff;
  background: #ec5151;
  height: 30px;
  margin: 0;
}

cart.js:

Page({
    data: {
        iscart: false,
        cart: [], //数据
        count: 1,   //商品数量默认是1
        total: 0,    //总金额
        goodsCount: 0 //数量
    },
    onLoad: function (options) {
       
    },
    onShow: function () {
        var that = this;
        // 获取产品展示页保存的缓存数据(购物车的缓存数组,没有数据,则赋予一个空数组)
        var arr = wx.getStorageSync('cart') || [];
        // 有数据的话,就遍历数据,计算总金额 和 总数量
        if (arr.length > 0) {
            for (var i in arr) {
                that.data.total += Number(arr[i].price) * Number(arr[i].count);
                that.data.goodsCount += Number(arr[i].count);
            }
            // 更新数据
            this.setData({
                iscart: true,
                cart: arr,
                total: that.data.total,
                goodsCount: that.data.goodsCount
            });
        }
    },
    onHide: function(){
        // 清除数据
        this.setData({
            iscart: false,
            cart: [], //数据
            total: 0,    //总金额
            goodsCount: 0 //数量
        });
    },
    /* 减数 */
    delCount: function (e) {
        console.log(e)
        // 获取购物车该商品的数量
        // [获取设置在该btn的id,即list的index值]
        if (this.data.cart[e.target.id.substring(3)].count <= 1) {
            return;
        }
        // 商品总数量-1
        this.data.goodsCount -= 1;
        // 总价钱 减去 对应项的价钱单价
        this.data.total -= Number(this.data.cart[e.target.id.substring(3)].price);
        // 购物车主体数据对应的项的数量-1  并赋给主体数据对应的项内
        this.data.cart[e.target.id.substring(3)].count = --this.data.cart[e.target.id.substring(3)].count;
        // 更新data数据对象
        this.setData({
            cart: this.data.cart,
            total: this.data.total,
            goodsCount: this.data.goodsCount
        })
        // 主体数据重新赋入缓存内
        try {
            wx.setStorageSync('cart', this.data.cart)
        } catch (e) {
            console.log(e)
        }
    },
    /* 加数 */
    addCount: function (e) {
        // 商品总数量+1
        this.data.goodsCount += 1;
        // 总价钱 加上 对应项的价钱单价
        this.data.total += Number(this.data.cart[e.target.id.substring(3)].price);
        // 购物车主体数据对应的项的数量+1  并赋给主体数据对应的项内
        this.data.cart[e.target.id.substring(3)].count = ++this.data.cart[e.target.id.substring(3)].count;
        // 更新data数据对象
        this.setData({
            cart: this.data.cart,
            total: this.data.total,
            goodsCount: this.data.goodsCount
        })
        // 主体数据重新赋入缓存内
        try {
            wx.setStorageSync('cart', this.data.cart)
        } catch (e) {
            console.log(e)
        }
    },
    /* 删除item */
    delGoods: function (e) {
        // 商品总数量  减去  对应删除项的数量
        this.data.goodsCount = this.data.goodsCount - this.data.cart[e.target.id.substring(3)].count;
        // 总价钱  减去  对应删除项的单价*数量
        this.data.total -= this.data.cart[e.target.id.substring(3)].price * this.data.cart[e.target.id.substring(3)].count;
        // 主体数据的数组移除该项
        this.data.cart.splice(e.target.id.substring(3), 1);
        // 更新data数据对象
        this.setData({
            cart: this.data.cart,
            total: this.data.total,
            goodsCount: this.data.goodsCount
        })
        // 主体数据重新赋入缓存内
        try {
            wx.setStorageSync('cart', this.data.cart)
        } catch (e) {
            console.log(e)
        }
    }
})

运行结果:

demo:http://download.csdn.net/detail/michael_ouyang/9825344
原文链接:https://blog.csdn.net/michael_ouyang/article/details/70755892

发布了461 篇原创文章 · 获赞 736 · 访问量 21万+

猜你喜欢

转载自blog.csdn.net/weixin_43901866/article/details/105657362