加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 资源网站 > 资源 > 正文

微信小程序之购物车和父子组件传值及calc的注意事项

发布时间:2020-12-14 19:31:29 所属栏目:资源 来源:网络整理
导读:1.效果图 2.子组件实现 要实现图中删除的效果,使用组件的形式更好做点,我当时本想直接在pages里实现,不过结果就是,滑动时,所有的商品都显示了删除按钮,除非用数组将每个商品要移动的距离存储起来,不过这样的话就很麻烦,所以我也是用组件来实现的 关

1.效果图

2.子组件实现

  • 要实现图中删除的效果,使用组件的形式更好做点,我当时本想直接在pages里实现,不过结果就是,滑动时,所有的商品都显示了删除按钮,除非用数组将每个商品要移动的距离存储起来,不过这样的话就很麻烦,所以我也是用组件来实现的
  • 关于微信组件,可以直接点击链接访问官网查看自定义组件
  • 子组件index.wxml
<view class="commodityItem" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove" style="transform:translateX({{-rightSpace}}px)">
  "selectedBtn" bindtap="handleSelect" data-is-selected="{{commodity.isselected}}">
    "noSelected" wx:if={{commodity.isselected==0}}"></view>
    <image "selectedImg" wx:else src="/images/selected.png"></image>
  </view>
  "commodityInfo">
    "commodityImg">
      {{commodity.image}}</image>          
    "commodityTitle">
      "title">{{commodity.title}}</view>
      "standard">规格:{{commodity.standard?commodity.standard:'无'}}"count">
        "price">¥{{commodity.price}}</view>
        "commodityNum">
          <i-input-number value={{selectedNum}}" min="1" max={{commodity.stock}}bindchange="numChange" />
        "deleteBtn">
    "deleteImg" "/images/delete.png"></image>
    <text "deleteText">删除</text>
  </view>
</view>
  • 子组件index.wxss
/* 商品 */
.commodityItem{
  display: flex;
  position: relative;
  padding: 10rpx 24rpx 20rpx 30rpx;
  box-sizing: border-box;
  background: #fff;
  transition: all .5s;
}
/* 选择按钮 */
.selectedBtn{
  align-items: center;
  width: 80rpx;
}
.noSelected{
  46rpx;
  height: border-radius: 50%;
  border: 1px solid #ef5225;
}
.selectedBtn .selectedImg{
  50rpx;
  50rpx;
}
/* 商品信息 */
.commodityInfo{
  width: calc(100% - 80rpx);
}
.commodityImg{
  margin-right: 18rpx;
  220rpx;
  220rpx;
}
.commodityImg image{
  100%;
  vertical-align: middle;  
}
/* 商品title */
.commodityTitle{
  calc(100% - 220rpx);
}
.title{
  display: -webkit-box;
  70rpx;
  line-height:35rpx;
  font-size: 24rpx;
  font-weight:600;
  overflow: hidden;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.standard{
  padding-top: 16rpx;
  90rpx;
  box-sizing: border-box;
}
.count{
  justify-content: space-between;
  60rpx;
}

/* 删除按钮 */
.deleteBtn{
  position: absolute;
  70px;
  top: 0rpx;
  right: -flex-direction: column;
  justify-content: center;
  #ef5225;
}
.deleteImg{
  margin-bottom: 10rpx;
  vertical-align: middle;
}
.deleteText{
  color: #fff;
}
  • 子组件index.json,这里用了iview中的数字输入框
{
  "component": true,"usingComponents": {
    "i-input-number": "/component/iview/input-number/index"
  }
}
  • 子组件index.js
Component({

  properties: {
    commodity: Object,},data: {
    touchStart: null,rightSpace: 0,selectedNum: 1,methods: {
    /* 商品是否选中 */
    handleSelect() {
            let selectedNum = this.data.selectedNum;
      let commodity = this.data.commodity;
      if(commodity.isselected == 0) {
        commodity.isselected = 1;
      } else {
        commodity.isselected = 0;
      }
            this.triggerEvent('handleselect',{ commodity,selectedNum})
    },/* 处理触摸滑动开始 */
    handleTouchStart(e) {
      /* 记录触摸滑动初始位置 */
      let touchStart = e.changedTouches[0].clientX;
      this.setData({
        touchStart
      })
    },136);">/* 处理触摸滑动 */
    handleTouchMove(e) {
      console.log(e)
      let moveSpace = e.changedTouches[0].clientX;
      let touchStart = this.data.touchStart;
      if (touchStart != null) {
        if (moveSpace - touchStart > 70) {
          this.setData({
            touchStart: 0
          })
        }
        else if (moveSpace - touchStart < -70) {
          this.setData({
            touchStart: 70
          })
        }
      }
    },numChange(e) {
        let selectedNum = e.detail.value;
        let commodity = this.data.commodity;
        this.setData({
            selectedNum
        })
        this.triggerEvent(3.父组件实现
  • 父组件index.wxml,这里用的是假数据,所以操作上会有一些是联调时不必要的操作
  • 父组件index.wxss
  • page{
      #f8f8f8;
    }
    .cart{
        padding-bottom: 100rpx;
      26rpx;
    }
    .item{
      border-bottom: #eee;
    }
    /* 头部店铺信息 */
    .storeInfo{
      18rpx 0rpx box-sizing: border-box;
    }
    .storeInfo .avatar{
      56rpx;
      vertical-align: middle;
    }
    .storeInfo .storeName{
      margin-left: line-height: 56rpx;
    }
    /* 包邮信息 */
    .discount{
      padding-left: height:font-size:20rpx;
      #666;
      box-sizing: border-box;
    }
    /* 底部操作 */
    .count{
        display: flex;
        position: fixed;
        30rpx;
        bottom: 0;
      left: 0;
        100%;
        100rpx;
        #232323;
        /* 全选 */
    .selectAll{
        padding-right: 20rpx;
        align-items: center;
        25%;
      30rpx;
    }
    .selectAll .noSelected{
      #ef5225;
    }
    .selectAll .selectedImg{
      50rpx;
    }
    .selectAllText{
        18rpx;
    }
    
    .countPrice{
        right: 270rpx;
      text-align: center;
      30rpx;
    }
    .countPrice text{
      15rpx;
    }
    .account{
      #ef5225;
      父组件index.json,引用子组件
    
    {
      "usingComponents": {
        "cart-item": "/component/cart/index"
      }
    }
    • 父组件index.js
    Page({
    
      data: {
        cartList: [
          {
            shopname: '猫咪小店',logo: '/images/avatar.jpeg',128);">shopid: 11,128);">commodity: [
              {
                id: 1,image:'/images/commodity.jpg',128);">title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',128);">standard: '111 + 黑色',128);">price: '100',128);">stock: 10,128);">quantity: isselected:  2,68);">'/images/avatar7.jpg',68);">'10',128);">5,}
            ]
          },{
            '/images/avatar5.jpg',128);">450,68);"> 3,68);">'90',68);"> 4,68);"> 5,128);">2,128);">550,68);"> 6,68);">'/images/avatar8.jpg',],136);">/* 商品是否全选中 */
            isSelectedAll: false,136);">/* 已选中商品的价格 */
            countPrice: /* 统计所有选中的商品数量 */
        countSelectedNum: /* 处理商品选中 */
      handleSelect(e) {
            let countPrice = 0;
        let countSelectedNum = 0;
        let cartList = this.data.cartList;
        let length = cartList.length;
    
            /* 因为是假数据,所以需要循环查找到对应的数据将其替换 */
        for(let i = 0; i < length; i++) {
          for(let j = 0; j < cartList[i].commodity.length; j++) {
                    if (cartList[i].commodity[j].id == e.detail.commodity.id) {
              cartList[i].commodity[j] = e.detail.commodity;
              cartList[i].commodity[j].selectedNum = e.detail.selectedNum;
            }
            if (cartList[i].commodity[j].isselected == 1) {
              /* 点击选中的时候,计算价格,要判断下设置的商品选中数量,
               * 我这里的是对点击了的商品才设置了选中的数量,所以需要对没有点击的商品数量设置为1,然后就默认的加一
               */
              if (cartList[i].commodity[j].selectedNum != undefined) {
                countPrice += cartList[i].commodity[j].price * cartList[i].commodity[j].selectedNum;
                countSelectedNum += cartList[i].commodity[j].selectedNum
              } else {
                countPrice += cartList[i].commodity[j].price * 1;
                countSelectedNum += 1;
              }
            }
          }
        }
    
            /* 对是否全选中进行判断 */
            let isSelectedAll = true;
            for (let i = 0; i < length; i++) {
                for (let j = 0; j < cartList[i].commodity.length; j++) {
                    /* 若商品中的isselecetd有为0的就终止循环,直接设置为未全选 */
                    if (cartList[i].commodity[j].isselected == 0) {
                        isSelectedAll = false;
                        break;
                    }
                }
            }
    
        this.setData({
          cartList,isSelectedAll,countPrice,countSelectedNum
        })
      },136);">/* 全选中商品 */
        handleSelectAll() {
            let isSelectedAll = !this.data.isSelectedAll;
            let cartList = this.data.cartList;
            let length = cartList.length;
        let countPrice = 0;
    
            /* 遍历数据中的isselected来进行全选的操作 */
            for(let i = 0; j < cartList[i].commodity.length; j++) {
                    if(isSelectedAll) {
                        cartList[i].commodity[j].isselected = 1;
              /* 全选的时候,计算价格,要判断下设置的商品选中数量,
               * 我这里的是对点击了的商品才设置了选中的数量,所以需要对没有点击的商品数量设置为1,然后就默认加一
               */
              if (cartList[i].commodity[j].selectedNum != undefined) {
                countPrice += parseInt(cartList[i].commodity[j].price) * cartList[i].commodity[j].selectedNum;
                countSelectedNum += cartList[i].commodity[j].selectedNum;
              } 1;    
                countSelectedNum += 1;        
              }
                    } else {
                        cartList[i].commodity[j].isselected = 0;
                    }
                }
            }
    
            this.setData({
                isSelectedAll,cartList,countSelectedNum
            })
        },})

    4.父子组件传值

    • 较常用的都是父组件往子组件传值,所以子组件往父组件传值就会不是很熟悉
    • 我这里的话,是因为用的假数据,在点击商品选中或者不选中时,需要改变商品里的选中属性,所以用到了子组件往父组件传值,也包括传递选中的商品数量
    • 子组件往父组件传值的话,是通过在调用this.triggerEvent()来实现的
  • 在子组件中调用
  • this.triggerEvent(handleSelect(e) {
        console.log(e.detail)
        console.log(e.detail.commodity)
        console.log(e.detail.selectedNum)
    }

    5.calc的注意事项

    • 我以前也遇到过,然后现在再用的时候,一时间把这点给忘了,在看到编译器样式的时候,才猛然想起
    .user-content{
        10px 0 50px;
        calc(100% - 50px);  /* 计算宽度,'+'或'-'符号前后有空格 */
        18px;
    }
    • css中使用calc可以进行简单的运算:
    • 单位可以是百分比,px,rem,em等单位
    • 使用"+","-","*","/"运算符(使用"+"或者"-"符号时,符号前后必须加上空格)
    • 在Firefox浏览器上使用要加上-moz前缀
    • chrome浏览器上使用要加上-webkit前缀
    • (使用"+"或者"-"符号时,符号前后必须加上空格)

    6.部分想法

    • 其实在样式上还是挺快就完成了,就是在计算商品价格的时候,想了挺久
    • 在计算价格时,当时就有点蒙圈,总是想着要怎么判断他是增加数量还是减少数量,然后就陷入死循环的之中。
    • 其实不用想她是增加还是减少数量,因为你都是传的是商品的数量,而且在计算时,也是判断了商品是否选中,所以,直接点,计算价格乘以数量就可以了
    • 然后选中的商品数量的统计就和计算价格的思路是一样的了
    正在努力学习中,若对你的学习有帮助,留下你的印记呗(点个赞咯^_^)
    • 往期好文推荐:

      • 判断iOS和Android及PC端
      • css实现波浪线及立方体
      • 微信小程序中遇到的多规格问题(一)
      • 实现单行及多行文字省略号

    (编辑:李大同)

    【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

      推荐文章
        热点阅读