商城购物车的小逻辑
效果如下:
代码如下:
wxml:
<view class="main">
<view wx:if="{{hasList}}" >
<view class="cart-box auto" >
<view class="cart-list content" wx:for="{{carts}}" wx:key="{{index}}" class="touch-item {{item.isTouchMove ? 'touch-move-active' : ''}}" data-index="{{index}}" bindtouchstart="touchstart" bindtouchmove="touchmove">
<icon wx:if="{{item.selected}}" type="success" color="red" data-index="{{index}}" style='margin-top:90rpx;' class='ml10 mr10' bindtap="selectList"/>
<icon wx:else type="circle" style='margin-top:90rpx;' class='ml10 mr10' data-index="{{index}}" bindtap="selectList"/>
<navigator url="../details/details?id={{item.id}}">
<image class="cart-thumb" src="{{item.image}}"></image>
</navigator>
<view>
<text class=" mt30 ml20 ib w100">{{item.title}}</text>
<text class=" mt10 ml20 cor6 f28 ib w100">{{item.hanl}}</text> <text class=" mt40 ml20 price ib w100 f29">¥ {{item.price}}</text>
</view>
<view class="cart-count-box">
<text class="cart-count-down" bindtap="minusCount" data-obj="{{obj}}" data-index="{{index}}">-</text>
<text class="cart-count-num">{{item.num}}</text>
<text class="cart-count-add" bindtap="addCount" data-index="{{index}}">+</text>
</view>
<text class="del" bindtap="deleteList" data-index="{{index}}">删除</text>
</view>
</view>
<view class="cart-footer">
<icon wx:if="{{selectAllStatus}}" type="success_circle" color="red" class="total-select" bindtap="selectAll"/>
<icon wx:else type="circle" class="total-select" bindtap="selectAll"/> <view class="order-icon">
<navigator url="../settlement/settlement">
<text class='f30'>去结算</text>
</navigator>
</view>
<text class='f30'>全选</text>
<view class="cart-toatl-price">
<text class='fl ib f34' style='margin-top:-18rpx;'>合计:</text>
<text class='fl ib f34 price' style='margin-top:-18rpx;'>{{totalPrice}}</text>
<text class='fl f24' style='margin-top:-53rpx;'>(不含运费和优惠)</text>
</view>
</view>
</view>
<view wx:else>
<view class="cart-no-data">购物车是空的哦~</view>
</view>
</view>
js:
Page({
data: {
startX: 0, //开始坐标
startY: 0,
carts: [], // 购物车列表
hasList: false, // 列表是否有数据
totalPrice: 0, // 总价,初始为0
selectAllStatus: true, // 全选状态,默认全选
obj: { name: "hello" } }, onShow() { this.setData({ hasList: true, carts: [ { id: 1, title: '牛蒡净爽洁面乳', hanl:'100ml', image: '../../images/goods/goodsimg.png', num: 4, price:99.9, selected: true }, { id: 2, title: '牛蒡倍润修护霜', hanl: '100ml', image: '../../images/goods/goods.png', num: 1, price: 88.9, selected: true }, { id: 3, title: '牛蒡倍润护手霜 ', hanl: '100ml', image: '../../images/goods/fenl2.jpg', num: 1, price: 77.9, selected: true } ] }); this.getTotalPrice();
},
/** * 当前商品选中事件 */
selectList(e) {
const index = e.currentTarget.dataset.index;
let carts = this.data.carts;
const selected = carts[index].selected;
carts[index].selected = !selected;
this.setData({ carts: carts });
this.getTotalPrice();
},
/** * 删除购物车当前商品 */
deleteList(e) {
const index = e.currentTarget.dataset.index;
let carts = this.data.carts;
carts.splice(index, 1);
this.setData({
carts: carts
});
if (!carts.length) {
this.setData({
hasList: false
});
} else {
this.getTotalPrice();
}
},
/** * 购物车全选事件 */
selectAll(e) {
let selectAllStatus = this.data.selectAllStatus;
selectAllStatus = !selectAllStatus;
let carts = this.data.carts;
for (let i = 0; i < carts.length; i++) {
carts[i].selected = selectAllStatus;
}
this.setData({
selectAllStatus: selectAllStatus,
carts: carts
});
this.getTotalPrice();
},
/** * 绑定加数量事件 */
addCount(e) {
const index = e.currentTarget.dataset.index;
let carts = this.data.carts;
let num = carts[index].num;
num = num + 1;
carts[index].num = num;
this.setData({
carts: carts
});
this.getTotalPrice();
},
/** * 绑定减数量事件 */
minusCount(e) {
const index = e.currentTarget.dataset.index;
const obj = e.currentTarget.dataset.obj;
let carts = this.data.carts;
let num = carts[index].num;
if (num <= 1) {
return false;
}
num = num - 1;
carts[index].num = num;
this.setData({
carts: carts
});
this.getTotalPrice();
},
/** * 计算总价 */
getTotalPrice() {
let carts = this.data.carts; // 获取购物车列表
let total = 0;
for (let i = 0; i < carts.length; i++) {
// 循环列表得到每个数据
if (carts[i].selected) {
// 判断选中才会计算价格
total += carts[i].num * carts[i].price;
// 所有价格加起来
}
}
this.setData({ // 最后赋值到data中渲染到页面
carts: carts,
totalPrice: total.toFixed(2)
});
},
onLoad: function () {
this.setData({
carts: this.data.carts,
})
},
//手指触摸动作开始 记录起点X坐标
touchstart: function (e) {
//开始触摸时 重置所有删除
this.data.carts.forEach(function (v, i) {
if (v.isTouchMove)//只操作为true的
v.isTouchMove = false;
})
this.setData({
startX: e.changedTouches[0].clientX,
startY: e.changedTouches[0].clientY,
carts: this.data.carts
})
},
//滑动事件处理
touchmove: function (e) {
var that = this,
index = e.currentTarget.dataset.index,//当前索引
startX = that.data.startX,//开始X坐标
startY = that.data.startY,//开始Y坐标
touchMoveX = e.changedTouches[0].clientX,//滑动变化坐标
touchMoveY = e.changedTouches[0].clientY,//滑动变化坐标
//获取滑动角度
angle = that.angle({
X: startX, Y: startY
}, {
X: touchMoveX, Y: touchMoveY
});
that.data.carts.forEach(function (v, i) {
v.isTouchMove = false
//滑动超过30度角 return
if (Math.abs(angle) > 30) return;
if (i == index) {
if (touchMoveX > startX) //右滑
v.isTouchMove = false
else //左滑
v.isTouchMove = true
}
})
//更新数据
that.setData({
carts: that.data.carts
})
},
/**
* 计算滑动角度
* @param {Object} start 起点坐标
* * @param {Object} end 终点坐标
* */
angle: function (start, end) {
var _X = end.X - start.X,
_Y = end.Y - start.Y //返回角度 /Math.atan()返回数字的反正切值
return 360 * Math.atan(_Y / _X) / (2 * Math.PI);
}
wxss:
page{ background: #eee;}.touch-item { font-size: 14px; display: flex; justify-content: space-between; width: 96%; overflow: hidden; margin: 0 2%; background: #fff; height:230rpx; margin-top: 10rpx; position: relative;}/* .content { width: 100%; padding: 10px; line-height: 22px; margin-right:0; -webkit-transition: all 0.4s; transition: all 0.4s; -webkit-transform: translateX(90px); transform: translateX(90px); margin-left: -90px; } */.del { background-color: orangered; width: 110rpx; display: flex; flex-direction: column; align-items: center; justify-content: center; color: #fff; -webkit-transform: translateX(90px); transform: translateX(90px); -webkit-transition: all 0.4s; transition: all 0.4s;}.touch-move-active .cart-list,.touch-move-active .del { -webkit-transform: translateX(0); transform: translateX(0);}.cart-thumb{ width: 170rpx; height: 170rpx; margin-top: 30rpx;}
.cart-box{ padding-bottom: 100rpx;}
.cart-list .cart-pro-select{ position: absolute; left: 20rpx; top: 90rpx; width: 45rpx; height: 45rpx;}.price{ color: red;} .cart-count-box{ position: absolute; right: 75rpx; text-align: right; top: 150rpx; width: 250rpx; height: 80rpx;}
.cart-count-down,.cart-count-add{ font-size: 44rpx; width: 50rpx; height: 100%; margin-right: 15rpx;}.cart-count-add{ margin-left: 10rpx;}.cart-count-num{ width: 150rpx;}.cart-footer{ position: fixed; bottom: 0; left: 0; width: 100%; height: 95rpx; line-height: 95rpx; padding:0 100rpx 0 80rpx; box-sizing: border-box; background: #fff; color: #666;}.total-select{ position: absolute; left: 20rpx; top: 25rpx; width: 45rpx; height: 45rpx;}.order-icon{ position: absolute; right: 0rpx; width: 150rpx; text-align: center; background: #cccccc;}
.cart-toatl-price{ float: right; width: 280rpx;}
.cart-no-data{ padding:40rpx 0; color: #999; text-align: center;}.navigator-hover { background-color:rgba(255, 255, 255, 0.1); opacity:0.7;}
代码思路大概就是这样!
欢迎提意见!