Browse Source

新增购物车滑动删除功能

master
邓平艺 4 years ago
parent
commit
a927ecd347
  1. 290
      components/lf-swipeAction/lf-swipeAction.vue
  2. 61
      pages/store/cart/cart.vue

290
components/lf-swipeAction/lf-swipeAction.vue

@ -0,0 +1,290 @@
<template>
<view class="swipe_action_box" @touchstart="onTouchstart" @touchmove="onTouchmove" @touchcancel="onTouchcancel" @touchend="onTouchend">
<view class="swipe_action_item" :style="{ width: (screenWidth + maxWidth) + 'px', transform: 'translateX(' + translateX + 'px)', transition: 'transform ' + animationTime + 'ms cubic-bezier(.165, .84, .44, 1)' }">
<view class="swipe_action_content"><slot></slot></view>
<view class="swipe_action_btn_box" ref="swipeActionBtnBox" :class="{'mune-show': mune_show}">
<view v-for="(item,index) of options" :key="index" class="swipe_action_btn" :style="{
backgroundColor: item.style && item.style.backgroundColor ? item.style.backgroundColor : '#C7C6CD'
}" @click.stop="onBtn(index,item)">
<text :style="{
fontSize: item.style && item.style.fontSize ? item.style.fontSize : '14px',
color: item.style && item.style.color ? item.style.color : '#FFFFFF'
}">{{ item.text }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom');
// #endif
export default {
props: {
/**
* 按钮内容
*/
options: {
type: Array,
default () {
return []
}
},
/**
* 禁用
*/
disabled: {
type: Boolean,
default: false
},
/**
* 变量控制开关
*/
show: {
type: Boolean,
default: false
},
/**
* 是否自动关闭
*/
autoClose: {
type: Boolean,
default: true
},
/**
* swipe-action 的索引值
*/
index: {
type: Number,
default: 0
}
},
data() {
return {
//
startTime: 0,
//
touchStartX: 0,
//
maxWidth: 58,
//
translateX: 0,
animationTime: 0,
//
currentX: 0,
screenWidth: 0,
mune_show: false
};
},
watch:{
show(val){
if(val){
this.animationTime = 350;
this.translateX = -this.maxWidth;
}else {
this.animationTime = 350;
this.translateX = 0;
}
},
translateX(val){
if(val == 0){
this.mune_show = false;
}else{
this.mune_show = true;
}
}
},
created() {
let systemInfo = uni.getSystemInfoSync();
this.screenWidth = systemInfo.screenWidth;
},
mounted() {
const _this = this;
setTimeout(() => {
// #ifdef APP-NVUE
dom.getComponentRect(this.$refs['swipeActionBtnBox'], (data) => {
_this.maxWidth = data.size.width;
if(_this.show){
_this.animationTime = 350;
_this.translateX = -data.size.width;
}
});
// #endif
// #ifndef APP-NVUE
uni.createSelectorQuery().in(this).selectAll('.swipe_action_btn_box')
.boundingClientRect(data => {
_this.maxWidth = data[0].width;
if(_this.show){
_this.animationTime = 350;
_this.translateX = -data[0].width;
}
}).exec()
// #endif
},500);
},
//
methods: {
onBtn(index, item) {
this.$emit('button', {
content: item,
index: this.index,
buttonIndex: index
});
if(this.autoClose){
this.animationTime = 350;
this.translateX = 0;
}
},
//
onTouchstart(e) {
if(this.disabled){
return;
}
//
// #ifdef APP-NVUE
this.touchStartX = e.changedTouches[0].screenX;
// #endif
// #ifndef APP-NVUE
this.touchStartX = e.changedTouches[0].clientX;
// #endif
this.startTime = new Date().getTime();
this.currentX = this.translateX;
},
//
onTouchmove(e) {
if(this.disabled){
return;
}
//
// #ifdef APP-NVUE
const clientX = e.changedTouches[0].screenX;
// #endif
// #ifndef APP-NVUE
const clientX = e.changedTouches[0].clientX;
// #endif
//
const difference = this.touchStartX - clientX;
//
if (difference > 0) {
//
const leftDifference = this.currentX - Math.abs(difference);
//
if (this.maxWidth < Math.abs(leftDifference)) {
this.animationTime = 0;
this.translateX = -this.maxWidth;
} else {
this.animationTime = 0;
this.translateX = leftDifference;
}
} else {
const rightDifference = this.currentX + Math.abs(difference);
if (0 < rightDifference) {
this.animationTime = 0;
this.translateX = 0;
} else {
this.animationTime = 0;
this.translateX = rightDifference;
}
}
},
//
onTouchcancel(e) {
if(this.disabled){
return;
}
// #ifdef APP-NVUE
this.finallySlide(e.changedTouches[0].screenX);
// #endif
// #ifndef APP-NVUE
this.finallySlide(e.changedTouches[0].clientX);
// #endif
},
//
onTouchend(e) {
if(this.disabled){
return;
}
// #ifdef APP-NVUE
this.finallySlide(e.changedTouches[0].screenX);
// #endif
// #ifndef APP-NVUE
this.finallySlide(e.changedTouches[0].clientX);
// #endif
},
//
finallySlide(finallyX) {
//
const endTime = new Date().getTime();
//
const timeDifference = endTime - this.startTime;
//
const distanceDifference = this.touchStartX - finallyX;
//
if (distanceDifference > 0) {
// 3 3004
if (Math.abs(this.translateX) > this.maxWidth / 2 || (timeDifference < 300 && distanceDifference > this.maxWidth / 4)) {
this.animationTime = 350;
this.translateX = -this.maxWidth;
} else {
this.animationTime = 350;
this.translateX = 0;
}
} else if (distanceDifference < 0) {
// 3 3004
if (Math.abs(this.translateX) < this.maxWidth / 2 || (timeDifference < 300 && Math.abs(distanceDifference) > this.maxWidth / 4)) {
this.animationTime = 350;
this.translateX = 0;
} else {
this.animationTime = 350;
this.translateX = -this.maxWidth;
}
}
}
}
};
</script>
<style scoped>
.swipe_action_box {
overflow: hidden;
width: 750rpx;
}
.swipe_action_item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
}
.swipe_action_content {
/* width: 750rpx; */
width: max-content;
/* #ifndef APP-NVUE */
flex-shrink: 0;
/* #endif */
}
.swipe_action_btn_box {
/* #ifndef APP-NVUE */
display: flex;
flex-shrink: 0;
/* #endif */
flex-direction: row;
visibility: hidden;
}
.mune-show{
visibility: initial;
}
.swipe_action_btn {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: row;
align-items: center;
justify-content: center;
padding: 0 30rpx;
}
.swipe_action_btn:nth-child(1){
margin-left: 20rpx;
}
</style>

61
pages/store/cart/cart.vue

@ -16,20 +16,25 @@
</view>
<view class="red-tag" @click="$msg('敬请期待')">去凑单</view>
</view>
<view v-for="(g_item, g_index) in s_item.goods" :key="g_index" class="lf-row-between">
<u-checkbox-group>
<u-checkbox shape="circle" active-color="#15716E" @change="goodsCheckChange($event, s_index, g_index)" v-model="g_item.checked"></u-checkbox>
</u-checkbox-group>
<view class="lf-m-t-30" style="display: flex;">
<image class="content-img" :src="g_item.img" mode="aspectFill" @click="$url('/pages/shop/goodsdetail')"></image>
<view class="lf-m-l-15 content-info">
<view class="lf-color-333 lf-font-26 lf-line-2" style="max-width: 480rpx;">{{g_item.name}}</view>
<view class="lf-font-24 lf-color-777 lf-m-t-14 lf-row-between">
<view>{{g_item.count}}{{g_item.spec}}</view>
<view class="lf-font-32 lf-color-price">{{ g_item.price }}</view>
<!-- 单个商品信息增加滑动删除 -->
<view v-for="(g_item, g_index) in s_item.goods" :key="g_index">
<lf-swipe-action :options="options" :index="g_index" :show="show" @button="onButton($event, s_index)">
<view class="lf-row-between">
<u-checkbox-group>
<u-checkbox shape="circle" active-color="#15716E" @change="goodsCheckChange($event, s_index, g_index)" v-model="g_item.checked"></u-checkbox>
</u-checkbox-group>
<view class="lf-m-t-30" style="display: flex;">
<image class="content-img" :src="g_item.img" mode="aspectFill" @click="$url('/pages/shop/goodsdetail')"></image>
<view class="lf-m-l-15 content-info">
<view class="lf-color-333 lf-font-26 lf-line-2" style="max-width: 480rpx;">{{g_item.name}}</view>
<view class="lf-font-24 lf-color-777 lf-m-t-14 lf-row-between">
<view>{{g_item.count}}{{g_item.spec}}</view>
<view class="lf-font-32 lf-color-price">{{ g_item.price }}</view>
</view>
</view>
</view>
</view>
</view>
</lf-swipe-action>
</view>
</view>
</view>
@ -54,14 +59,30 @@
</template>
<script>
import lfSwipeAction from '@/components/lf-swipeAction/lf-swipeAction.vue';
export default {
components: {
lfSwipeAction
},
data() {
return {
token: '', // token
allChecked: false, //
list: [], //
total_price: '', //
total_count: '' //
total_count: '', //
options: [{
text: '删除',
style: {
backgroundColor: '#dd524d'
}
},{
text: '取消',
style: {
backgroundColor: '#15716E'
}
}],
show: false
}
},
watch: {
@ -156,6 +177,19 @@
}else{
this.$msg('您未选择需要结算的商品');
}
},
//
onButton(event, parentIndex){
console.log("event", event, parentIndex);
if(event.buttonIndex == 0){
uni.showModal({
title: '温馨提示',
content: '确定移除该商品吗?',
success: result => {
}
})
}
}
}
}
@ -217,6 +251,7 @@
// margin-bottom: 30rpx;
padding: 30rpx;
margin: 30rpx auto;
overflow: hidden;
&:last-child {
margin-bottom: 150rpx;
}

Loading…
Cancel
Save