uniapp 实现小程序列表项左滑菜单

互联网 2022/1/19 17:20:35

最近使用uniapp做一些小程序的功能;需要在列表项中左滑实现菜单功能,之前没有什么经验,所以参考网上的各种文章最终才实现的功能;这里记录一下实现过程; 先看视图页面:<scroll-view v-if="myCustomerList.length!=0" :style="height:+ height&quo…

最近使用uniapp做一些小程序的功能;需要在列表项中左滑实现菜单功能,之前没有什么经验,所以参考网上的各种文章最终才实现的功能;这里记录一下实现过程;

先看视图页面:

<scroll-view v-if="myCustomerList.length!=0" :style="'height:'+ height" scroll-y lower-threshold="30"
                @scrolltolower="LoadMoreMyCustomers">
                <view v-for="(item,index) in myCustomerList" :key="index" class="touch-item"
                    :class="item.IsTouchMove?'touch-move-active':''" :data-index="index" @touchstart="touchStartMyItem"
                    @touchmove="touchMoveMyItem">
                    <view class="itemcontent">
                        ......
                    </view>
                    <view class="itembtn" style="background-color: red;">删除</view>
                </view>
            </scroll-view>

上边的代码就是列表的基本界面代码,其中主要有几个点需要注意:

1、IsTouchMove是判断当前项已经左滑,在获得到列表后首先要给每一项添加这个属性默认值为false

2、touchstart和touchmove是拖动单个项的关键事件

3、class="touch-item"是单个项的样式,需要注意的是touch-move-active样式是当IsTouchMove时才需要设置的,否则不设置;

4、class="itemcontent"是内容样式

5、class="itembtn"是左滑后显示的菜单样式

内容和菜单需要平级

下边再看下样式部分:

.touch-item {
        background-color: #F8F9FC;
        display: flex;
        justify-content: space-between;
        width: 100%;
        overflow: hidden
    }

    .itemcontent {
        display: flex;
        flex-direction: column;
        padding: 5px 10px;
        border-bottom: 1px solid #eeeeee;
        margin-right: 0;
        margin-left: -100px;
        width: 100%;
        -webkit-transition: all 0.4s;
        transition: all 0.4s;
        -webkit-transform: translateX(100px);
        transform: translateX(100px);
        position: relative;
    }

    .itembtn {
        width: 100px;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        background-color: #119bf8;
        color: white;
        position: relative;
        -webkit-transform: translateX(100px);
        transform: translateX(100px);
        -webkit-transition: all 0.4s;
        transition: all 0.4s;
    }

    .touch-move-active .itemcontent,
    .touch-move-active .itembtn {
        -webkit-transform: translateX(0);
        transform: translateX(0);
    }

样式部分注意点:

1、需要设置单个项的宽度为100%,禁止滚动;

2、itemcontent的margin-left为负值,绝对值和itembtn的宽度要一致;并且itemcontent的宽度要默认为width: 100%,这样才能默认占满整行;

3、itemcontent和itembtn的translateX都是itembtn的宽度

最后看下实现逻辑:

touchStartMyItem(e) {
                this.myCustomerList.forEach(item => {
                    if (item.IsTouchMove) {
                        item.IsTouchMove = false;
                    }
                    this.startX = e.changedTouches[0].clientX;
                    this.startY = e.changedTouches[0].clientY;
                })
            },
            touchMoveMyItem(e) {
                let that = this;

                let index = e.currentTarget.dataset.index; //当前索引
                let startX = that.startX; //开始X坐标
                let startY = that.startY; //开始Y坐标
                let touchMoveX = e.changedTouches[0].clientX; //滑动变化坐标
                let touchMoveY = e.changedTouches[0].clientY; //滑动变化坐标

                //获取滑动角度
                let angle = that.angle({
                    X: startX,
                    Y: startY
                }, {
                    X: touchMoveX,
                    Y: touchMoveY
                });
                /滑动超过30度角 return
                if (Math.abs(angle) > 30) return;
                that.myCustomerList.forEach((element, i) => {

                    element.IsTouchMove = false
if (i == index) {
                        if (touchMoveX > startX) { //右滑
                            element.IsTouchMove = false;
                        } else { //左滑
                            element.IsTouchMove = true;
                        }
                    }
                })
            },
            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);
            }

这两个方法就是核心的左滑方法,是网上找的内容,具体哪个网站忘了;我把循环稍作修改;

angle方法是计算滑动角度的方法,防止误操作;

原理就是滑动开始时,先循环将所有项设置为默认状态,然后记录当前项的坐标值;

在滑动时获得当前坐标,计算滑动角度,大于30度直接返回;然后循环找到对应item,根据滑动后的x值和滑动开始时x值之间的关系确定是左滑还是右滑,最后修改对应属性值;

 

随时随地学软件编程-关注百度小程序和微信小程序
关于找一找教程网

本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[uniapp 实现小程序列表项左滑菜单]http://www.zyiz.net/tech/detail-287433.html

赞(0)
关注微信小程序
程序员编程王-随时随地学编程

扫描二维码或查找【程序员编程王】

可以随时随地学编程啦!

技术文章导航 更多>