溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

微信小程序中購物車、父子組件傳值及calc的注意事項有哪些

發(fā)布時間:2021-07-19 09:33:48 來源:億速云 閱讀:172 作者:小新 欄目:web開發(fā)

這篇文章將為大家詳細(xì)講解有關(guān)微信小程序中購物車、父子組件傳值及calc的注意事項有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。

1.效果圖

微信小程序中購物車、父子組件傳值及calc的注意事項有哪些

2.子組件實現(xiàn)

要實現(xiàn)圖中刪除的效果,使用組件的形式更好做點,我當(dāng)時本想直接在pages里實現(xiàn),不過結(jié)果就是,滑動時,所有的商品都顯示了刪除按鈕,除非用數(shù)組將每個商品要移動的距離存儲起來,不過這樣的話就很麻煩,所以我也是用組件來實現(xiàn)的

關(guān)于微信組件,可以直接點擊鏈接訪問官網(wǎng)查看自定義組件

子組件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">規(guī)格:{{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中的數(shù)字輸入框

{
 "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.父組件實現(xiàn)

父組件index.wxml,這里用的是假數(shù)據(jù),所以操作上會有一些是聯(lián)調(diào)時不必要的操作

<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>結(jié)算</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,
 /* 統(tǒng)計所有選中的商品數(shù)量 */
 countSelectedNum: 0,
 },
 /* 處理商品選中 */
 handleSelect(e) {
  let countPrice = 0;
 let countSelectedNum = 0;
 let cartList = this.data.cartList;
 let length = cartList.length;

  /* 因為是假數(shù)據(jù),所以需要循環(huán)查找到對應(yīng)的數(shù)據(jù)將其替換 */
 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) {
   /* 點擊選中的時候,計算價格,要判斷下設(shè)置的商品選中數(shù)量,
   * 我這里的是對點擊了的商品才設(shè)置了選中的數(shù)量,所以需要對沒有點擊的商品數(shù)量設(shè)置為1,然后就默認(rèn)的加一
   */
   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;
   }
  }
  }
 }

  /* 對是否全選中進(jìn)行判斷 */
  let isSelectedAll = true;
  for (let i = 0; i < length; i++) {
   for (let j = 0; j < cartList[i].commodity.length; j++) {
    /* 若商品中的isselecetd有為0的就終止循環(huán),直接設(shè)置為未全選 */
    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;

  /* 遍歷數(shù)據(jù)中的isselected來進(jìn)行全選的操作 */
  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;
   /* 全選的時候,計算價格,要判斷下設(shè)置的商品選中數(shù)量,
   * 我這里的是對點擊了的商品才設(shè)置了選中的數(shù)量,所以需要對沒有點擊的商品數(shù)量設(shè)置為1,然后就默認(rèn)加一
   */
   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.父子組件傳值

較常用的都是父組件往子組件傳值,所以子組件往父組件傳值就會不是很熟悉

我這里的話,是因為用的假數(shù)據(jù),在點擊商品選中或者不選中時,需要改變商品里的選中屬性,所以用到了子組件往父組件傳值,也包括傳遞選中的商品數(shù)量

子組件往父組件傳值的話,是通過在調(diào)用this.triggerEvent()來實現(xiàn)的

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

在子組件中調(diào)用

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

這個this.triggerEvent('handleselect', { commodity, selectedNum })方法中,handleselect的名稱要與父組件中引用子組件時綁定的方法名稱一樣,后面的對象就是傳遞的值,也可以直接是以直接量的形式傳遞,然后再父組件中通過e.detail來獲取對應(yīng)的值

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

5.calc的注意事項

我以前也遇到過,然后現(xiàn)在再用的時候,一時間把這點給忘了,在看到編譯器樣式的時候,才猛然想起

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

css中使用calc可以進(jìn)行簡單的運算:

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

使用"+","-","*","/"運算符(使用"+"或者"-"符號時,符號前后必須加上空格)

在Firefox瀏覽器上使用要加上-moz前綴

chrome瀏覽器上使用要加上-webkit前綴

(使用"+"或者"-"符號時,符號前后必須加上空格)

6.部分想法

其實在樣式上還是挺快就完成了,就是在計算商品價格的時候,想了挺久

在計算價格時,當(dāng)時就有點蒙圈,總是想著要怎么判斷他是增加數(shù)量還是減少數(shù)量,然后就陷入死循環(huán)的之中。

其實不用想她是增加還是減少數(shù)量,因為你都是傳的是商品的數(shù)量,而且在計算時,也是判斷了商品是否選中,所以,直接點,計算價格乘以數(shù)量就可以了

然后選中的商品數(shù)量的統(tǒng)計就和計算價格的思路是一樣的了

關(guān)于“微信小程序中購物車、父子組件傳值及calc的注意事項有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI