index.vue 5.68 KB
<template lang="html">
  <div class="container">
    <ul>
      <li class="list-item " v-for="(item,index) in list " data-type="0">
          <div class="list-box" @touchstart.capture="touchStart" @touchend.capture="touchEnd" @click="clickItem($event, item)" :data-id="item.id">
              <div class="list-content">
                <p class="title">{{item.title}}</p>
              </div>
          </div>
          <div class="edit" @click="editItem($event, item)" :data-index="index" :data-id="item.id">修 改</div>
          <div class="delete" @click="deleteItem" :data-index="index" :data-id="item.id">删 除</div>
      </li>
    </ul>
  </div>
</template>

<script>
/**
 * [list 左滑修改删除列表]
 * @type {Array}
 * @field {id, title}
 *
 * [clickItem 点击表单项回调, 返回 index]
 * @type {Function}
 * @callback {index}
 *
 * [editItem 左滑点击表单编辑回调, 返回 index]]
 * @type {Function}
 * @callback {index}
 *
 * [deleteItem 左滑点击表单删除回调, 返回 index]]
 * @type {Function}
 * @callback {index}
 */
export default{
  name: 'index',
  props: ['list'],
  data () {
    return {
      startX: 0,
      endX: 0
    }
  },
  methods: {
   // 跳转
    clickItem (e, item) {
      if (this.checkSlide()) {
        this.restSlide();
      } else {
        // 当前ID
        let id = e.currentTarget.dataset.id;
        this.$emit('clickItem', id, item)
      }
    },
   // 滑动开始
    touchStart (e) {
      // 记录初始位置
      this.startX = e.touches[0].clientX;
    },
   // 滑动结束
    touchEnd (e) {
      // 当前滑动的父级元素
      let parentElement = e.currentTarget.parentElement;
      // 记录结束位置
      this.endX = e.changedTouches[0].clientX;

      // 左滑
      if (parentElement.dataset.type == 0 && this.startX - this.endX > 30) {
        this.restSlide();
        parentElement.dataset.type = 1;
      }

      // 右滑
      if (parentElement.dataset.type == 1 && this.startX - this.endX < -30) {
        this.restSlide();
        parentElement.dataset.type = 0;
      }

      this.startX = 0;
      this.endX = 0;
    },
    // 判断当前是否有滑块处于滑动状态
    checkSlide () {
      let listItems = document.querySelectorAll('.list-item');

      for (let i = 0; i < listItems.length; i++) {
        if (listItems[i].dataset.type == 1) {
          return true;
        }
      }
      return false;
    },
    // 复位滑动状态
    restSlide () {
      let listItems = document.querySelectorAll('.list-item');
      // 复位
      for (let i = 0; i < listItems.length; i++) {
        listItems[i].dataset.type = 0;
      }
    },
    // 删除
    deleteItem (e) {
      // 当前索引
      let index = e.currentTarget.dataset.index;
      // 复位
      this.restSlide();
      // 删除
      // this.list.splice(index, 1);
      // 当前ID
      // let id = e.currentTarget.dataset.id;
      this.$emit('deleteItem', index)
    },
    // 修改
    editItem (e, item) {
      // 当前索引
      let id = e.currentTarget.dataset.id;
      // 复位
      this.restSlide();
      // 当前ID
      this.$emit('editItem', id, item)
    }
  }
}
</script>

<style scoped>
.page-title{
    text-align: center;
    font-size: 17px;
    padding: 10px 15px;
    position: relative;
}
.page-title:after{
    content: " ";
    position: absolute;
    left: 0;
    bottom: 0;
    right: 0;
    height: 1px;
    border-bottom: 1px solid #ccc;
    color: #ccc;
    -webkit-transform-origin: 0 100%;
    transform-origin: 0 100%;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    z-index: 2;
}
.list-item{
    position: relative;
    height: 3.5rem;
    -webkit-transition: all 0.2s;
    transition: all 0.2s;
}
.list-item[data-type="0"]{
    transform: translate3d(0,0,0);
}
.list-item[data-type="1"]{
    transform: translate3d(-12rem,0,0);
}
.list-item:after{
    content: " ";
    position: absolute;
    /* left: 0.6rem; */
    left: 0rem;
    bottom: 0;
    right: 0;
    height: 1px;
    border-bottom: 1px solid #ebeaee;
    color: #ccc;
    -webkit-transform-origin: 0 100%;
    transform-origin: 0 100%;
    -webkit-transform: scaleY(0.5);
    transform: scaleY(0.5);
    z-index: 2;
}
.list-box{
    padding: 0.6rem;
    background: #fff;
    display: flex;
    align-items: center;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    justify-content: flex-end;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    font-size: 0;
}
.list-item .list-img{
    display: block;
    width: 3rem;
    height: 3rem;
}
.list-item .list-content{
    padding: 0.3rem 0 0.3rem 0.6rem;
    position: relative;
    flex: 1;
    flex-direction: column;
    align-items: flex-start;
    justify-content: center;
    overflow: hidden;
}
.list-item .title{
    display: block;
    color: #333;
    overflow: hidden;
    font-size: 15px;
    font-weight: bold;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.list-item .tips{
    display: block;
    overflow: hidden;
    font-size: 12px;
    color: #999;
    line-height: 20px;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.list-item .time{
    display: block;
    font-size: 12px;
    position: absolute;
    right: 0;
    top: 0.3rem;
    color: #666;
}
.list-item .delete{
    width: 6rem;
    height: 3.5rem;
    background: #fc6621;
    font-size: 17px;
    color: #fff;
    text-align: center;
    line-height: 3.5rem;
    position: absolute;
    top:0;
    right: -12rem;
}
.list-item .edit{
    width: 6rem;
    height: 3.5rem;
    background: #f0eff5;
    font-size: 17px;
    color: #000;
    text-align: center;
    line-height: 3.5rem;
    position: absolute;
    top:0;
    right: -6.1rem;
    border-left: 1px solid #ebeaee;
}
</style>