微信小程序購(gòu)物車、父子組件傳值及calc的注意事項(xiàng)總結(jié)
前言
在做微信小程序時(shí),覺(jué)得小組里對(duì)購(gòu)物車的實(shí)現(xiàn)不是很完美,就自己嘗試的寫了下,然后用到了父子組件傳值,父子組件傳值的話,和vue框架上是非常相似的,以及calc這個(gè)css函數(shù),calc有個(gè)注意點(diǎn),自己不怎么用,一時(shí)間有差點(diǎn)忘了,這里記錄下
下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧
1.效果圖

2.子組件實(shí)現(xiàn)
要實(shí)現(xiàn)圖中刪除的效果,使用組件的形式更好做點(diǎn),我當(dāng)時(shí)本想直接在pages里實(shí)現(xiàn),不過(guò)結(jié)果就是,滑動(dòng)時(shí),所有的商品都顯示了刪除按鈕,除非用數(shù)組將每個(gè)商品要移動(dòng)的距離存儲(chǔ)起來(lái),不過(guò)這樣的話就很麻煩,所以我也是用組件來(lái)實(shí)現(xiàn)的
關(guān)于微信組件,可以直接點(diǎn)擊鏈接訪問(wèn)官網(wǎng)查看自定義組件
子組件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">規(guī)格:{{commodity.standard?commodity.standard:'無(wú)'}}</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})
},
/* 處理觸摸滑動(dòng)開始 */
handleTouchStart(e) {
/* 記錄觸摸滑動(dòng)初始位置 */
let touchStart = e.changedTouches[0].clientX;
this.setData({
touchStart
})
},
/* 處理觸摸滑動(dòng) */
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.父組件實(shí)現(xiàn)
父組件index.wxml,這里用的是假數(shù)據(jù),所以操作上會(huì)有一些是聯(lián)調(diào)時(shí)不必要的操作
<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>合計(jì):</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: '雅詩(shī)蘭黛鮮活煥亮紅石榴晚霜50ml 補(bǔ)水保濕 滋潤(rùn)排濁',
standard: '111 + 黑色',
price: '100',
stock: 10,
quantity: 1,
isselected: 0,
},
{
id: 2,
image:'/images/avatar7.jpg',
title: '雅詩(shī)蘭黛鮮活煥亮紅石榴晚霜50ml 補(bǔ)水保濕 滋潤(rùn)排濁',
price: '10',
stock: 5,
quantity: 1,
isselected: 0,
}
]
},
{
shopname: '貓咪小店',
logo: '/images/avatar5.jpg',
shopid: 450,
commodity: [
{
id: 3,
image:'/images/commodity.jpg',
title: '雅詩(shī)蘭黛鮮活煥亮紅石榴晚霜50ml 補(bǔ)水保濕 滋潤(rùn)排濁',
price: '90',
stock: 10,
quantity: 1,
isselected: 0,
},
{
id: 4,
image:'/images/avatar7.jpg',
title: '雅詩(shī)蘭黛鮮活煥亮紅石榴晚霜50ml 補(bǔ)水保濕 滋潤(rùn)排濁',
price: '100',
stock: 5,
quantity: 1,
isselected: 0,
},
{
id: 5,
image:'/images/commodity.jpg',
title: '雅詩(shī)蘭黛鮮活煥亮紅石榴晚霜50ml 補(bǔ)水保濕 滋潤(rùn)排濁',
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: '雅詩(shī)蘭黛鮮活煥亮紅石榴晚霜50ml 補(bǔ)水保濕 滋潤(rùn)排濁',
standard: '111 + 黑色',
price: '100',
stock: 1,
quantity: 1,
isselected: 0,
}
]
},
],
/* 商品是否全選中 */
isSelectedAll: false,
/* 已選中商品的價(jià)格 */
countPrice: 0,
/* 統(tǒng)計(jì)所有選中的商品數(shù)量 */
countSelectedNum: 0,
},
/* 處理商品選中 */
handleSelect(e) {
let countPrice = 0;
let countSelectedNum = 0;
let cartList = this.data.cartList;
let length = cartList.length;
/* 因?yàn)槭羌贁?shù)據(jù),所以需要循環(huán)查找到對(duì)應(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) {
/* 點(diǎn)擊選中的時(shí)候,計(jì)算價(jià)格,要判斷下設(shè)置的商品選中數(shù)量,
* 我這里的是對(duì)點(diǎn)擊了的商品才設(shè)置了選中的數(shù)量,所以需要對(duì)沒(méi)有點(diǎn)擊的商品數(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;
}
}
}
}
/* 對(duì)是否全選中進(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來(lái)進(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í)候,計(jì)算價(jià)格,要判斷下設(shè)置的商品選中數(shù)量,
* 我這里的是對(duì)點(diǎn)擊了的商品才設(shè)置了選中的數(shù)量,所以需要對(duì)沒(méi)有點(diǎn)擊的商品數(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.父子組件傳值
較常用的都是父組件往子組件傳值,所以子組件往父組件傳值就會(huì)不是很熟悉
我這里的話,是因?yàn)橛玫募贁?shù)據(jù),在點(diǎn)擊商品選中或者不選中時(shí),需要改變商品里的選中屬性,所以用到了子組件往父組件傳值,也包括傳遞選中的商品數(shù)量
子組件往父組件傳值的話,是通過(guò)在調(diào)用this.triggerEvent()來(lái)實(shí)現(xiàn)的
/* 在父組件中定義方法:bind:handleselect或者也可以直接寫成bindhandleselect*/
<cart-item commodity="{{item}}" bind:handleselect="handleSelect" />
在子組件中調(diào)用
this.triggerEvent('handleselect', { commodity, selectedNum})
這個(gè)this.triggerEvent('handleselect', { commodity, selectedNum })方法中,handleselect的名稱要與父組件中引用子組件時(shí)綁定的方法名稱一樣,后面的對(duì)象就是傳遞的值,也可以直接是以直接量的形式傳遞,然后再父組件中通過(guò)e.detail來(lái)獲取對(duì)應(yīng)的值
handleSelect(e) {
console.log(e.detail)
console.log(e.detail.commodity)
console.log(e.detail.selectedNum)
}
5.calc的注意事項(xiàng)
我以前也遇到過(guò),然后現(xiàn)在再用的時(shí)候,一時(shí)間把這點(diǎn)給忘了,在看到編譯器樣式的時(shí)候,才猛然想起
.user-content{
padding: 10px 0 10px 50px;
width: calc(100% - 50px); /* 計(jì)算寬度,'+'或'-'符號(hào)前后有空格 */
height: 18px;
}
css中使用calc可以進(jìn)行簡(jiǎn)單的運(yùn)算:
單位可以是百分比,px,rem,em等單位
使用"+","-","*","/"運(yùn)算符(使用"+"或者"-"符號(hào)時(shí),符號(hào)前后必須加上空格)
在Firefox瀏覽器上使用要加上-moz前綴
chrome瀏覽器上使用要加上-webkit前綴
(使用"+"或者"-"符號(hào)時(shí),符號(hào)前后必須加上空格)
6.部分想法
其實(shí)在樣式上還是挺快就完成了,就是在計(jì)算商品價(jià)格的時(shí)候,想了挺久
在計(jì)算價(jià)格時(shí),當(dāng)時(shí)就有點(diǎn)蒙圈,總是想著要怎么判斷他是增加數(shù)量還是減少數(shù)量,然后就陷入死循環(huán)的之中。
其實(shí)不用想她是增加還是減少數(shù)量,因?yàn)槟愣际莻鞯氖巧唐返臄?shù)量,而且在計(jì)算時(shí),也是判斷了商品是否選中,所以,直接點(diǎn),計(jì)算價(jià)格乘以數(shù)量就可以了
然后選中的商品數(shù)量的統(tǒng)計(jì)就和計(jì)算價(jià)格的思路是一樣的了
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
微信小程序?qū)崿F(xiàn)商品數(shù)據(jù)聯(lián)動(dòng)效果
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)商品數(shù)據(jù)聯(lián)動(dòng)效果,代碼很簡(jiǎn)單,直接復(fù)制即可根據(jù)自己的需求去修改,對(duì)小程序商品數(shù)據(jù)聯(lián)動(dòng)實(shí)例代碼感興趣的朋友一起看看吧2022-08-08
JS中的六種繼承方式以及優(yōu)缺點(diǎn)總結(jié)
JS作為面向?qū)ο蟮娜躅愋驼Z(yǔ)言,繼承也是其非常強(qiáng)大的特性之一,那么如何在JS中實(shí)現(xiàn)繼承呢?下面這篇文章主要給大家介紹了關(guān)于JS中六種繼承方式以及優(yōu)缺點(diǎn)的相關(guān)資料,需要的朋友可以參考下2021-10-10
JavaScript基礎(chǔ)入門之錯(cuò)誤捕獲機(jī)制
初級(jí)開發(fā)人員往往很少使用js的拋出和捕獲異常,但拋出和捕獲異常往往是非常必要的,這篇文章主要給大家介紹了關(guān)于JavaScript基礎(chǔ)入門之錯(cuò)誤捕獲機(jī)制的相關(guān)資料,需要的朋友可以參考下2021-08-08
Javascrip實(shí)現(xiàn)文字跳動(dòng)特效
這篇文章主要介紹了Javascrip實(shí)現(xiàn)文字跳動(dòng)特效的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11

