原生微信小程序(实现左滑出现“删除”按钮)

302 阅读2分钟

效果

image.png

wxml

注意:

1、其中使用bindtouchstart来监听左滑开始、如果使用catchtouchstart监听那么会出现整个标签里面的bindtap/catchtap失效,因为在catchtouchstart时就已经监听并打断了里面的事件,所以此处使用bindtouchstart来监听滑动开始

2、使用catchtouchmove来实现滑动、如果使用bindtouchmove会出现页面颤抖情况

<!-- 内容列表 -->
<view class="data_view">
  <view class="item_view {{item.status ? '' :'active'}}" wx:for="{{dataList}}">
    <view class="content" bindtouchstart="touchStart" catchtouchmove="touchMove" data-index="{{index}}">
    <view class="{{item.active == 'ACTIVE' ? 'item_active' : 'item_active inactive'}}">{{activeOptions[item.active]}}</view>
    <view class="item_icon">
      <image src="../../images/main/common/staff.png" alt="员工icon" mode="widthFix" />
    </view>
    <view class="item_obj">
      <view class="item_name">{{item.staffName}}</view>
      <view class="item_no">
        <view>员工编号:{{item.staffNo}}</view>
        <view class="look_detail" data-item="{{item}}" catchtap="lookDetail">查看详情<van-icon name="arrow" /></view>
      </view>
    </view>
  </view>
  <view class="del_button {{item.active=='ACTIVE' ? 'active_del' : ''}}" catchtap="deleteStaff" data-item="{{item}}">删除</view>
  </view>
</view>

js

// data中的数据
data: {
    dataList: [{
        staffNo: '000001',
        staffName: 'XXXX',
        active: 'ACTIVE',
        status: true,
      },
      {
        staffNo: '000002',
        staffName: 'XXXX',
        active: 'INACTIVE',
        status: true,
      },
      {
        staffNo: '000003',
        staffName: 'XXXX',
        active: 'ACTIVE',
        status: true,
      },
      {
        staffNo: '000004',
        staffName: 'XXXX',
        active: 'INACTIVE',
        status: true,
      },
      {
        staffNo: '000005',
        staffName: 'XXXX',
        active: 'ACTIVE',
        status: true,
      },
    ],
    activeOptions: {
      ACTIVE: '启用',
      INACTIVE: '禁用',
    },
  },
  
  
  /**
   * 删除,只有数据为ACTIVE的才允许删除
   * @param {*} e 
   */
  deleteStaff(e) {
    let that = this;
    let item = e.currentTarget.dataset.item;
    if(item.active == 'ACTIVE') {
      return
    }
    console.log('删除', item);
    Dialog.confirm({
      title: '提示',
      message: '是否确认删除该员工',
    })
      .then(() => {
        // on confirm
      })
      .catch(() => {
        // on cancel
      });
  },
  /**
   * 查看详情
   * @param {*} e 
   */
  lookDetail(e) {
    let that = this;
    let item = e.currentTarget.dataset.item;
    console.log('查看详情');
  },
  /**
   * 移动
   * @param {*} e 
   */
  touchMove(e) {
    let that = this;
    let index = e.currentTarget.dataset.index;
    let name = `dataList[${index}].status`;
    let dataList = [];
    that.data.dataList.forEach(item => {
      item.status = true;
      dataList.push(item)
    })
    that.setData({
      dataList
    })
    // 获得当前坐标
    that.currentX = e.touches[0].clientX;
    that.currentY = e.touches[0].clientY;
    const x = that.startX - that.currentX; //横向移动距离
    const y = Math.abs(that.startY - that.currentY); //纵向移动距离,若向左移动有点倾斜也可以接受
    if (x > 35 && y < 110) {
    //向左滑是显示删除
    that.setData({
      [name]: false
     })
    } else if (x < -35 && y < 110) {
    //向右滑
    that.setData({
      [name]: true
     })
    }
   },
   /**
    * 滑动开始
    * @param {*} e 
    */
   touchStart(e) {
    let that = this;
    // 获得起始坐标
    that.startX = e.touches[0].clientX;
    that.startY = e.touches[0].clientY;
   },

wxss

.data_view {
  padding: 0 20rpx;
  box-sizing: border-box;
}

.item_icon image {
  width: 60rpx;
  background: linear-gradient(#bad4ff, #ffffff);
  border-radius: 60rpx;
  padding: 6rpx;
  margin-right: 30rpx;
}
.item_obj {
  width: 90%;
}
.item_name {
  font-weight: bold;
  font-size: 32rpx;
}

.item_no {
  color: #666666;
  padding-top: 10rpx;
  box-sizing: border-box;
  display: flex;
  justify-content: space-between;
}
.item_active {
  position: absolute;
  top: 0;
  right: 0;
  border-radius: 0 20rpx 0 20rpx;
  background-color: #07C160;
  padding: 4rpx 20rpx;
  box-sizing: border-box;
  color: #ffffff;
}
.inactive {
  background-color: #666666;
}
.active .item_active {
  border-radius: 0 0 0 20rpx;
}
.item_view {
  position: relative;
  top: 0;
  width: 100%;
  height: 150rpx;
  background-color: #ffffff;
  border-radius: 20rpx;
  display: flex;
  align-items: center;
  margin-top: 20rpx;
  box-sizing: border-box;
  overflow: hidden;
}
.item_view .content {
  background-color: #ffffff;
  height: 100%;
  position: relative;
  left: 0;
  width: 100%;
  transition: all 0.3s;
  display: flex;
  align-items: center;
  padding: 30rpx 20rpx;
  box-sizing: border-box;
}
.item_view .del_button {
  position: absolute;
  right: -140rpx;
  width: 140rpx;
  height: 100%;
  background-color: #df3448;
  color: #fff;
  top: 0;
  text-align: center;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: all 0.3s;
  font-size: 24rpx;
}
.item_view .active_del {
  background-color: #cccccc;
}
.look_detail {
  color: #ff8833;
}
.item_view.active .content {
  left: -140rpx;
}
.item_view.active .del_button {
  right: 0;
}