国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

微信小程序購物車、父子組件傳值及calc的注意事項總結

2019-11-19 12:30:54
字體:
來源:轉載
供稿:網友

前言

在做微信小程序時,覺得小組里對購物車的實現不是很完美,就自己嘗試的寫了下,然后用到了父子組件傳值,父子組件傳值的話,和vue框架上是非常相似的,以及calc這個css函數,calc有個注意點,自己不怎么用,一時間有差點忘了,這里記錄下

下面話不多說了,來一起看看詳細的介紹吧

1.效果圖


2.子組件實現

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

關于微信組件,可以直接點擊鏈接訪問官網查看自定義組件

子組件index.wxml

<view class="commodityItem" bindtouchstart="handleTouchStart" bindtouchmove="handleTouchMove" style="transform:translateX({{-rightSpace}}px)"> <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.部分想法

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

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

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

然后選中的商品數量的統計就和計算價格的思路是一樣的了

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網的支持。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 邮箱| 墨竹工卡县| 祥云县| 交口县| 兴山县| 永昌县| 大姚县| 天津市| 文成县| 庐江县| 车致| 综艺| 都兰县| 富宁县| 江川县| 丰都县| 宣城市| 浦东新区| 汕尾市| 云林县| 赤城县| 黎平县| 峨眉山市| 阜阳市| 贡觉县| 平湖市| 鹿邑县| 江城| 安吉县| 安丘市| 岑巩县| 盈江县| 澄江县| 鹤山市| 巫溪县| 颍上县| 年辖:市辖区| 郁南县| 北安市| 丽江市| 宝山区|