温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

微信小程序中购物车、父子组件传值及calc的注意事项有哪些

发布时间:2021-07-19 09:33:48 来源:亿速云 阅读:222 作者:小新 栏目:web开发

这篇文章将为大家详细讲解有关微信小程序中购物车、父子组件传值及calc的注意事项有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

1.效果图

微信小程序中购物车、父子组件传值及calc的注意事项有哪些

2.子组件实现

要实现图中删除的效果,使用组件的形式更好做点,我当时本想直接在pages里实现,不过结果就是,滑动时,所有的商品都显示了删除按钮,除非用数组将每个商品要移动的距离存储起来,不过这样的话就很麻烦,所以我也是用组件来实现的

关于微信组件,可以直接点击链接访问官网查看自定义组件

子组件index.wxml

<view class="commodityItem" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove" >  <view class="selectedBtn" bindtap="handleSelect" data-is-selected="{{commodity.isselected}}">  <view class="noSelected" wx:if="{{commodity.isselected==0}}"></view>  <image class="selectedImg" wx:else src="/images/selected.png"></image>  </view>  <view class="commodityInfo">  <view class="commodityImg">  <image src="{{commodity.image}}"></image>    </view>  <view class="commodityTitle">  <view class="title">{{commodity.title}}</view>  <view class="standard">规格:{{commodity.standard?commodity.standard:'无'}}</view>  <view class="count">  <view class="price">¥{{commodity.price}}</view>  <view class="commodityNum">   <i-input-number value="{{selectedNum}}" min="1" max="{{commodity.stock}}" bindchange="numChange" />  </view>  </view>  </view>  </view>  <view class="deleteBtn">  <image class="deleteImg" src="/images/delete.png"></image>  <text class="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{  display: flex;  align-items: center;  width: 80rpx; } .noSelected{  width: 46rpx;  height: 46rpx;  border-radius: 50%;  border: 1px solid #ef5225; } .selectedBtn .selectedImg{  width: 50rpx;  height: 50rpx; } /* 商品信息 */ .commodityInfo{  display: flex;  width: calc(100% - 80rpx); } .commodityImg{  margin-right: 18rpx;  width: 220rpx;  height: 220rpx; } .commodityImg image{  width: 100%;  height: 100%;  vertical-align: middle;  } /* 商品title */ .commodityTitle{  width: calc(100% - 220rpx); } .title{  display: -webkit-box;  width: 100%;  height: 70rpx;  line-height:35rpx;  font-size: 24rpx;  font-weight:600;  overflow: hidden;  -webkit-line-clamp: 2;  -webkit-box-orient: vertical; } .standard{  padding-top: 16rpx;  width: 100%;  height: 90rpx;  box-sizing: border-box; } .count{  display: flex;  align-items: center;  justify-content: space-between;  width: 100%;  height: 60rpx; } /* 删除按钮 */ .deleteBtn{  display: flex;  position: absolute;  width: 70px;  height: 100%;  top: 0rpx;  right: -70px;  flex-direction: column;  align-items: center;  justify-content: center;  background: #ef5225; } .deleteImg{  margin-bottom: 10rpx;  width: 50rpx;  height: 50rpx;  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  })  },  /* 处理触摸滑动 */  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: null,   rightSpace: 0   })  }  else if (moveSpace - touchStart < -70) {   this.setData({   touchStart: null,   rightSpace: 70   })  }  }  },  numChange(e) {  let selectedNum = e.detail.value;  let commodity = this.data.commodity;  this.setData({   selectedNum  })  this.triggerEvent('handleselect', { commodity, selectedNum})  }  } })

3.父组件实现

父组件index.wxml,这里用的是假数据,所以操作上会有一些是联调时不必要的操作

<view class="cart">  <view class="item" wx:for="{{cartList}}" wx:key="{{items.shopid}}" wx:for-item="items">  <view class="storeInfo">   <image class="avatar" src="{{items.logo}}"></image>   <view class="storeName">{{items.shopname}}</view>  </view>  <view class="discount">满¥100包邮,满10件包邮</view>  <view class="commodity" wx:for="{{items.commodity}}" wx:key="{{item.id}}">   <cart-item commodity="{{item}}" bind:handleselect="handleSelect" />  </view>  </view>  <view class="count">   <view class="selectAll" bindtap="handleSelectAll">    <view class="noSelected" wx:if="{{!isSelectedAll}}"></view>   <image class="selectedImg" wx:else src="/images/selected.png"></image>    <text class="selectAllText">全选</text>   </view>   <view class="countPrice">   <text>合计:</text>   <text>¥{{countPrice}}</text>  </view>   <view class="account">   <text>结算</text>   <text>({{countSelectedNum}})</text>  </view>  </view> </view>

父组件index.wxss

page{  background: #f8f8f8; } .cart{  padding-bottom: 100rpx;  font-size: 26rpx; } .item{  border-bottom: 1px solid #eee; } /* 头部店铺信息 */ .storeInfo{  display: flex;  padding: 18rpx 0rpx 18rpx 30rpx;  background: #fff;  box-sizing: border-box; } .storeInfo .avatar{  width: 56rpx;  height: 56rpx;  border-radius: 50%;  vertical-align: middle; } .storeInfo .storeName{  margin-left: 16rpx;  line-height: 56rpx; } /* 包邮信息 */ .discount{  padding-left: 30rpx;  height:50rpx;  line-height: 50rpx;  font-size:20rpx;  color: #666;  box-sizing: border-box; } /* 底部操作 */ .count{  display: flex;  position: fixed;  padding-left: 30rpx;  bottom: 0;  left: 0;  width: 100%;  height: 100rpx;  line-height: 100rpx;  box-sizing: border-box;  color: #232323;  background: #eee; } /* 全选 */ .selectAll{  display: flex;  padding-right: 20rpx;  align-items: center;  width: 25%;  font-size: 30rpx; } .selectAll .noSelected{  width: 46rpx;  height: 46rpx;  border-radius: 50%;  border: 1px solid #ef5225; } .selectAll .selectedImg{  width: 50rpx;  height: 50rpx; } .selectAllText{  margin-left: 18rpx; } .countPrice{  position: absolute;  top: 0;  right: 270rpx;  height: 100%;  line-height: 100rpx;  text-align: center;  font-size: 30rpx; } .countPrice text{  margin-right: 15rpx; } .account{  position: absolute;  top: 0;  right: 0;  width: 270rpx;  height: 100%;  line-height: 100rpx;  text-align: center;  font-size: 30rpx;  background: #ef5225;  color: #fff; } 父组件index.json,引用子组件 {  "usingComponents": {  "cart-item": "/component/cart/index"  } }

父组件index.js

Page({  data: {  cartList: [   {   shopname: '猫咪小店',   logo: '/images/avatar.jpeg',   shopid: 11,   commodity: [    {    id: 1,    image:'/images/commodity.jpg',    title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',    standard: '111 + 黑色',    price: '100',    stock: 10,    quantity: 1,    isselected: 0,    },     {    id: 2,    image:'/images/avatar7.jpg',    title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',    price: '10',    stock: 5,    quantity: 1,    isselected: 0,    }   ]   },   {   shopname: '猫咪小店',   logo: '/images/avatar5.jpg',   shopid: 450,   commodity: [    {    id: 3,    image:'/images/commodity.jpg',    title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',    price: '90',    stock: 10,    quantity: 1,    isselected: 0,    },    {    id: 4,    image:'/images/avatar7.jpg',    title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',    price: '100',    stock: 5,    quantity: 1,    isselected: 0,    },     {    id: 5,    image:'/images/commodity.jpg',    title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',    standard: '111 + 黑色',    price: '100',    stock: 2,    quantity: 1,    isselected: 0,    }   ]   },   {   shopname: '猫咪小店',   logo: '/images/avatar.jpeg',   shopid: 550,   commodity: [    {    id: 6,    image:'/images/avatar8.jpg',    title: '雅诗兰黛鲜活焕亮红石榴晚霜50ml 补水保湿 滋润排浊',    standard: '111 + 黑色',    price: '100',    stock: 1,    quantity: 1,    isselected: 0,    }   ]   },  ],   /* 商品是否全选中 */   isSelectedAll: false,   /* 已选中商品的价格 */   countPrice: 0,  /* 统计所有选中的商品数量 */  countSelectedNum: 0,  },  /* 处理商品选中 */  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  })  },  /* 全选中商品 */  handleSelectAll() {   let isSelectedAll = !this.data.isSelectedAll;   let cartList = this.data.cartList;   let length = cartList.length;  let countPrice = 0;  let countSelectedNum = 0;   /* 遍历数据中的isselected来进行全选的操作 */   for(let i = 0; i < length; i++) {    for (let j = 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;    } else {    countPrice += cartList[i].commodity[j].price * 1;     countSelectedNum += 1;      }     } else {      cartList[i].commodity[j].isselected = 0;     }    }   }   this.setData({    isSelectedAll,    cartList,   countPrice,   countSelectedNum   })  }, })

4.父子组件传值

较常用的都是父组件往子组件传值,所以子组件往父组件传值就会不是很熟悉

我这里的话,是因为用的假数据,在点击商品选中或者不选中时,需要改变商品里的选中属性,所以用到了子组件往父组件传值,也包括传递选中的商品数量

子组件往父组件传值的话,是通过在调用this.triggerEvent()来实现的

/* 在父组件中定义方法:bind:handleselect或者也可以直接写成bindhandleselect*/ <cart-item commodity="{{item}}" bind:handleselect="handleSelect" />

在子组件中调用

this.triggerEvent('handleselect', { commodity, selectedNum})

这个this.triggerEvent('handleselect', { commodity, selectedNum })方法中,handleselect的名称要与父组件中引用子组件时绑定的方法名称一样,后面的对象就是传递的值,也可以直接是以直接量的形式传递,然后再父组件中通过e.detail来获取对应的值

handleSelect(e) {  console.log(e.detail)  console.log(e.detail.commodity)  console.log(e.detail.selectedNum) }

5.calc的注意事项

我以前也遇到过,然后现在再用的时候,一时间把这点给忘了,在看到编译器样式的时候,才猛然想起

.user-content{  padding: 10px 0 10px 50px;  width: calc(100% - 50px); /* 计算宽度,'+'或'-'符号前后有空格 */  height: 18px; }

css中使用calc可以进行简单的运算:

单位可以是百分比,px,rem,em等单位

使用"+","-","*","/"运算符(使用"+"或者"-"符号时,符号前后必须加上空格)

在Firefox浏览器上使用要加上-moz前缀

chrome浏览器上使用要加上-webkit前缀

(使用"+"或者"-"符号时,符号前后必须加上空格)

6.部分想法

其实在样式上还是挺快就完成了,就是在计算商品价格的时候,想了挺久

在计算价格时,当时就有点蒙圈,总是想着要怎么判断他是增加数量还是减少数量,然后就陷入死循环的之中。

其实不用想她是增加还是减少数量,因为你都是传的是商品的数量,而且在计算时,也是判断了商品是否选中,所以,直接点,计算价格乘以数量就可以了

然后选中的商品数量的统计就和计算价格的思路是一样的了

关于“微信小程序中购物车、父子组件传值及calc的注意事项有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI