美文网首页
Taro 实现 微信小程序滑动删除功能

Taro 实现 微信小程序滑动删除功能

作者: R_X | 来源:发表于2022-10-26 09:20 被阅读0次

需求:实现左滑删除功能

image.png

一、代码组成

  • SwipeCell.vue : 可左右滑动做删除等其他操作的组件
  • SwipeCell.less : 组件的样式表
  • combination.js
  • GoodsType.vue : 使用滑动组件的页面文件
1、SwipeCell.vue
<template>
    <!-- 可左右滑动做删除等其他操作的组件 -->
    <view
        class="swipe-cell"
    >
        <view
            :style="{
                'transition-duration': `${duration}s`,
                'transform': `translate3d(${movedDistance}rpx, 0rpx, 0rpx)`
            }"
            @touchstart="onTouchStart"
            @touchmove="onTouchMove"
            @touchend="onTouchEnd"
        >
            <view
                v-if="leftWidth"
                class="swipe-cell__left"
                @tap="slotClick('left')"
            >
                <slot name="left" />
            </view>
            <slot class="cell" />
            <view
                v-if="rightWidth"
                class="swipe-cell__right"
                @tap="slotClick('right')"
            >
                <slot name="right" />
            </view>
        </view>
    </view>
</template>
<script>
import './SwipeCell.less';
import { getDirection, resetTouchStatus } from '@/combination';

export default {
    name: 'SwipeCell',
    props: {
        duration: {
            type: Number,
            default: 0.4
        },
        // 右边slot 的宽度 rpx为单位
        rightWidth: {
            type: Number,
            default: 0
        },
        // 左边slot 的宽度 rpx为单位
        leftWidth: {
            type: Number,
            default: 0
        },
        // prop传进来的滑动距离
        propMovedDistance: {
            type: Number,
            default: 0
        }
    },
    data () {
        return {
            movedDistance: 0, // 元素应该滑动的距离
            activeIndex: 0, // 当前查看的tab的索引
            newTabList: [],
            xPositon: 0, // 容器在X轴移动的距离
            swipeable: true,
            swiping: false,
            direction: '',
            deltaX: 0,
            deltaY: 0,
            offsetX: 0,
            offsetY: 0,
            startX: 0,
            startY: 0,
            minSwipeDistance: 50
        };
    },
    watch: {
        propMovedDistance (val) {
            this.movedDistance = val;
        }
    },
    methods: {
        touchStart (event) {
            resetTouchStatus(this);
            var touch = event.touches[0];
            this.startX = touch.clientX;
            this.startY = touch.clientY;
        },
        touchMove (event) {
            var touch = event.touches[0];
            this.deltaX = touch.clientX - this.startX;
            this.deltaY = touch.clientY - this.startY;
            this.offsetX = Math.abs(this.deltaX);
            this.offsetY = Math.abs(this.deltaY);
            this.direction = this.direction || getDirection(this.offsetX, this.offsetY);
        },
        onTouchStart (event) {
            if (!this.swipeable) { return; }
            this.swiping = true;
            this.touchStart(event);
        },
        onTouchMove (event) {
            if (!this.swipeable || !this.swiping) { return; }
            this.touchMove(event);
        },
        // watch swipe touch end
        onTouchEnd () {
            if (!this.swipeable || !this.swiping) { return; }
            if (!this.leftWidth && this.deltaX > 0 && !this.movedDistance) return;
            if (!this.rightWidth && this.deltaX < 0 && !this.movedDistance) return;
            if (this.direction === 'horizontal' && this.offsetX >= this.minSwipeDistance) {
                this.movedDistance = this.deltaX > 0 ? this.leftWidth : -this.rightWidth;
            }
            this.swiping = false;
            this.$emit('swipeEnd', this.movedDistance);
        },
        slotClick (type) {
            this.movedDistance = 0;
            resetTouchStatus(this);
            this.$emit('close', type);
        },
        getMovedDistance () {
            return this.movedDistance;
        }
    }
};
</script>
2、SwipeCell.less
.swipe-cell {
    overflow: hidden;
    position: relative;
    &__left {
        position: absolute;
        top: 0;
        height: 100%;
        left: 0;
        transform: translate3d(-100%, 0, 0);
    }
    .cell {
    }
    &__right {
        position: absolute;
        top: 0;
        height: 100%;
        right: 0;
        transform: translate3d(100%, 0, 0);
    }
}
3、combination.js
/**
 * 获取滑动的方向,垂直、水平
 * @param {*} x
 * @param {*} y
 * @returns horizontal: 水平; vertical: 垂直
 */
export function getDirection (x, y) {
    var MIN_DISTANCE = 10;
    if (x > y && x > MIN_DISTANCE) {
        return 'horizontal';
    }
    if (y > x && y > MIN_DISTANCE) {
        return 'vertical';
    }
    return '';
}

export function resetTouchStatus (that) {
    that.direction = '';
    that.deltaX = 0;
    that.deltaY = 0;
    that.offsetX = 0;
    that.offsetY = 0;
}
4、GoodsType.vue
<template>
    <SwipeCell
        v-for="(item, ind) in records"
        :key="item.id"
        :right-width="122"
        :async-close="true"
        :propMovedDistance="ind === swipedIndex ? propMovedDistance : 0"
        @close="onClose"
        @swipeEnd="(distance) => swipeEndHandle(ind, distance)"
    >
        <view class="flex f-ai-c f-jc-sb goods-type">
            <view
                class="flex f-d-c goods-type-i flex1"
                @tap="toAddType(item.id)"
            >
                <text class="fz-30">
                    {{ item.typeName }}
                </text>
                <text
                    class="fz-28"
                    style="color: #999999;"
                >
                    商品数量{{ item.goodsCount || 0 }}
                </text>
            </view>
        </view>
        <template #right>
            <view
                class="del-btn flex f-ai-c f-jc-c fz-27 c-f"
                :style="{borderRadius: !ind ? '0 14rpx 0 0' : ind === records.length - 1 ? '0 0 14rpx 0' : '0'}"
                @tap="delItem(item)"
            >
                删除
            </view>
        </template>
    </SwipeCell>
</template>
<script>
export default {
    name: 'GoodsType',
    components: { SwipeCell },
    data () {
        return {
            records: [],
            swipedIndex: 0, // 当前左滑删除的元素的index
            propMovedDistance: 0 // 当前左滑删除的元素 移动的距离
        };
    },
     methods: {
        swipeEndHandle (ind, distance) {
            this.swipedIndex = ind;
            this.propMovedDistance = distance;
        },
        onClose (type) {
            switch (type) {
            case 'left':
            case 'right':
                Taro.showModal({
                    title: '提示',
                    content: '是否要删除',
                    success: (res) => {
                        if (res.confirm) {
                            typeDelete(this.delingid, true).then(res => {
                                if (res) {
                                    Taro.showToast({
                                        title: '操作成功',
                                        icon: 'success',
                                        duration: 1000
                                    });
                                    const index = this.records.findIndex(r => r.id === this.delingid);
                                    this.records.splice(index, 1);
                                }
                            });
                        }
                    }
                });
                break;
            }
        }
     }
}
</script>

相关文章

网友评论

      本文标题:Taro 实现 微信小程序滑动删除功能

      本文链接:https://www.haomeiwen.com/subject/otzazrtx.html