平常在使用QQ或者WX聊天,在消息列表中某一项左滑,会出现几个操作按钮,什么置顶啊,标记未读等等,下面用原生小程序实现一下这个功能
wxml部分
<!-- moveTarget 主要记录当前滑动或者关闭的状态 -->
<view class="list-group {{moveTarget=='move-box-'+index?('item-move'+(btnList.length>3?3:btnList.length)):''}}"
mut-bind:touchmove="touchListMove"
mut-bind:touchstart="touchListStrat"
data-target="move-box-{{index}}"
wx:for="{{reportDataList}}" wx:key="index">
<view class="box">
{{item}}
</view>
<!-- btnList,左滑后的按钮数组 -->
<view class="btn-group" wx:if="{{btnList.length>0}}">
<view wx:for="{{btnList}}" wx:key="index" class="btn" bindtap="tapBtn"
data-btnindex="{{index}}">
{{item}}
</view>
</view>
</view>
1.moveTarget
在标签中定义了 data-target="move-box-{{index}}" , 比如页面中有十个盒子,你滑动了第一个,那么对应取到的就是 move-box-0, 然后在方法中给moveTarget赋值 data-target ,当二者相同时,对应的盒子才可以滑动,如果不做这一层限制,就会导致滑动一个盒子,所有盒子一起动
2. mut-bind:touchmove="touchListMove" mut-bind:touchstart="touchListStrat"
对应的滑动开始和滑动结束的方法:mut-bind ,我也不是很理解很详细的意思,大概就是一个方法生效另一个也跟着生效,感兴趣的可以百度一下
3.{{moveTarget=='move-box-'+index?('item-move'+(btnList.length>3?3:btnList.length)):''}}
这里就是对应着 (1) 里面所说的,如果相等,找到对应的盒子,添加后面的类名,类名对应的样式中规定了向左滑动的宽度
wxss部分
/* 假设一个操作按钮的宽度为 166rpx,item-move1代表一个操作按钮的样式,依此类推 */
.list-group.item-move3{
transform: translateX(-500rpx);
}
.list-group.item-move2{
transform: translateX(-332rpx);
}
.list-group.item-move1{
transform: translateX(-166rpx);
}
.list-group {
position: relative;
height: 100rpx;
line-height: 100rpx;
width: 100%;
background-color: #f0f0f0;
margin-bottom: 10rpx;
transition: all .6s ease-in-out 0s;
}
/* 把操作按钮定位到盒子右侧,记得加 transform: translateX(100%); */
.btn-group {
position: absolute;
right: 0;
top: 0;
width: 500rpx;
height: 100%;
display: flex;
flex-direction: row;
transform: translateX(100%);
}
.btn-group .btn{
width: 166.5rpx;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
js部分
这里所有数据都是我自定义,实际可能后台获取数据
// pages/index/component/index.js
Component({
/**
* 页面的初始数据
*/
data: {
reportDataList: ['盒子1','盒子2'], // 页面盒子数组
btnList: ['按钮1','按钮2','按钮3'], // 操作按钮数组
moveStartX: 0, // 滑动距离
moveTarget: '', // 滑动控制
},
// 组件方法中心
methods: {
// 滑动开始
touchListStrat(e) {
this.setData({
moveStartX: e.touches[0].pageX
})
},
// 滑动结束
touchListMove(e) {
let moveEndX = e.touches[0].pageX;
let moveStartX = this.data.moveStartX;
let btnList = this.data.btnList;
if (btnList.length>0) {
let size = Math.abs(moveEndX - moveStartX);
if (moveEndX < moveStartX) {
if (size > 20) {
this.setData({
moveTarget: e.currentTarget.dataset.target
})
}
} else {
this.setData({
moveTarget: ''
})
}
}
},
// 点击行内按钮
tapBtn(e) {
let btnindex = e.currentTarget.dataset.btnindex;
// 在这里可以定义按钮点击事件
// 点击按钮时让moveTarget等于空,这样等于找不到当前你滑动的盒子,所以点击之后滑动就会恢复原样
this.setData({
moveTarget: ""
})
}
}
})
效果已经大致实现了