欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Vue 移动端拖拽交换位置

程序员文章站 2022-03-08 10:16:56
...
<template>
    <div class="imageUploaderPage">
        <ul ref='imgList' class="imgList">
            <li ref='imgItem'  class="imgCoverItem" v-for='(item, index) in filesResults' :key='index' @click="deleteImage(index)"
            :data-index='index'
            @touchstart="touchstart($event, item, index)"
            @touchmove="touchmove($event)"
            @touchend="touchend($event)" >
                <img :id="'avarimgs' + index" :src="item">
            </li>
            <li class="imgCoverItem upLoadImageWrapper">
                <input ref='upLoadImageFile' id='upLoadImage' type='file' multiple="multiple" accept="image/*" @change="change" />
            </li>
        </ul>
        <p>点击图片删除, 拖拽可更改顺序,共4张</p>
        <div class="btnConfimList" v-show="DeleteImageMask">
            <div class="btnConfimListMask" @click='setDelete(false)'></div>
            <transition name="transTop">
              <div class="btnConfimListContent">
                <ul>
                  <li class="borderT" >删除该图片?</li>
                  <li class="borderT" @click='setDelete(true)' style="color: var(--mRed);">删除</li>
                </ul>
                <p class="cancelDeleteImage" @click='setDelete(false)'>取消</p>
              </div>
            </transition>
        </div>
    </div>
</template>
<script>
export default {
  data () {
    return {
      files: [],
      fileItem: {},
      filesResults: [],
      DeleteImageMask: false,
      // isShow:false,
      startX: 0, // 开始触摸的位置
      startY: 0,
      moveX: 0, // 滑动时的位置
      moveY: 0,
      endX: 0,
      endY: 0, // 结束触摸的位置
      disX: 0, // 移动距离
      disY: 0,
      slideEffect: [], // 滑动时的效果
      target: null,
      startIndex: null,
      zindex: 1,
      leftW: 0,
      targetW: 0,
      clientW: 0,
      targetX: 0,
      targetY: 0,
      allItems: [],
      targetIndex: null
    }
  },
  // computed: {
  //   toRightW () { return (this.leftW + this.targetW) * (this.startIndex + 1) - this.startX },
  //   toLeftW () { return this.startX - (this.leftW + this.targetW) * this.startIndex },
  //   toTopH () { return this.startY - parseInt(this.startIndex / 4) * (this.topH + this.targetW) },
  //   toBottomH () { return (this.topH + this.targetW) - this.startY + (this.leftW + this.targetW) * (parseInt(this.startIndex / 4)) }
  // },
  mounted () {
    this.$nextTick(() => {
      this.absoluteItems()
    })
  },
  watch: {
    slideEffect (newV) {
      return newV
    }
  },
  methods: {
    change (e) {
      var fileItem = e.target.files
      let me = this
      for (let i = e.target.files.length - 1; i >= 0; i--) {
        var reader = new FileReader()
        var file = e.target.files[i]
        reader.onloadstart = function (e) {
          // console.log('开始读取....')
        }
        reader.onprogress = function (e) {
          // console.log('正在读取中....')
        }
        reader.onabort = function (e) {
          // console.log('中断读取....')
        }
        reader.onerror = function (e) {
          // console.log('读取异常....')
        }
        reader.onload = function (e) {
          if (me.filesResults.indexOf(e.target.result) >= 0) {
            me.$toast('请勿重复上传')
            return
          }
          if (me.files.length >= 7) {
            me.$toast('最多上传4张图片')
            return
          }
          me.files.unshift(fileItem)
          me.filesResults.unshift(e.target.result)
        }
        reader.readAsDataURL(file)
      }
    },
    absoluteItems () {
      for (let i = 0; i < 8; i++) {
        this.allItems = []
      }
    },
    deleteImage (index) {
      this.curIndex = index
      this.DeleteImageMask = true
    },
    setDelete (data) {
      this.DeleteImageMask = false
      this.curIndex = null
      data && this.curIndex >= 0 && this.files.splice(this.curIndex, 1) && this.filesResults.splice(this.curIndex, 1)
    },
    touchstart (e, item, index) {
      this.startIndex = index
      this.targetIndex = index
      this.target = e.target.nodeName.toLowerCase() === 'li' ? e.target : e.target.parentNode
      !this.leftW && (this.leftW = this.target.parentNode.querySelectorAll('li')[0].getBoundingClientRect().left)
      !this.topH && (this.topH = this.target.parentNode.querySelectorAll('li')[0].getBoundingClientRect().top)
      !this.targetW && (this.targetW = this.target.offsetWidth)
      !this.clientW && (this.clientW = this.leftW + this.targetW)
      this.zindex++
      this.target.style.zIndex = this.zindex
      this.startX = e.touches[0].clientX
      this.startY = e.touches[0].clientY
    },
    touchmove (ev) {
      ev = ev || window.event
      ev.preventDefault()
      if (ev.touches.length === 1) {
        this.moveX = ev.touches[0].clientX
        this.moveY = ev.touches[0].clientY
        this.disX = this.moveX - this.startX
        this.disY = this.moveY - this.startY
        // 边界处理
        this.disY <= 0 && (this.disY = 0)
        this.disY >= (this.$refs.imgList.offsetHeight - this.clientW) && (this.disY = this.$refs.imgList.offsetHeight - this.clientW)
        this.target.style.transform = 'translate3d(' + this.disX + 'px,' + this.disY + 'px, 0)'
        this.target.getBoundingClientRect().left <= 0 && (this.target.style.transform = 'translate3d(' + (-this.clientW * this.startIndex) + 'px,' + this.disY + 'px, 0)')
        this.target.getBoundingClientRect().right >= this.$refs.imgList.offsetWidth && (this.target.style.transform = 'translate3d(' + this.clientW * (3 - this.startIndex) + 'px,' + this.disY + 'px, 0)')
        for (let i = 0; i < this.filesResults.length; i++) {
          // && this.moveY > this.$refs.imgItem[i].getBoundingClientRect().top && this.moveY < this.$refs.imgItem[i].getBoundingClientRect().top + this.targetW
          if (this.moveX >= this.$refs.imgItem[i].getBoundingClientRect().left && this.moveX < this.$refs.imgItem[i].getBoundingClientRect().left + this.targetW && (i !== this.startIndex)) {
            if (i > this.targetIndex && this.moveX >= this.$refs.imgItem[i].getBoundingClientRect().left && this.moveX < this.$refs.imgItem[i].getBoundingClientRect().left + this.targetW) {
              if (this.$refs.imgItem[i].style.transform) {
                if (this.$refs.imgItem[i].style.transform === 'translate3d(0px, 0px, 0px)') {
                  this.$refs.imgItem[i].style.transform = 'translate3d(' + (-this.clientW) + 'px, 0, 0)'
                  this.targetIndex = i
                } else {
                  this.$refs.imgItem[i].style.transform = 'translate3d(0px, 0px, 0px)'
                  this.targetIndex = i - 1
                }
              } else {
                this.$refs.imgItem[i].style.transform = 'translate3d(' + (-this.clientW) + 'px, 0, 0)'
                this.targetIndex = i
              }
            } else if (i < this.targetIndex && this.moveX >= this.$refs.imgItem[i].getBoundingClientRect().left && this.moveX < this.$refs.imgItem[i].getBoundingClientRect().left + this.targetW) {
              if (this.$refs.imgItem[i].style.transform) {
                if (this.$refs.imgItem[i].style.transform === 'translate3d(0px, 0px, 0px)') {
                  this.$refs.imgItem[i].style.transform = 'translate3d(' + (this.clientW) + 'px, 0, 0)'
                  this.targetIndex = i
                } else {
                  this.$refs.imgItem[i].style.transform = 'translate3d(0px, 0px, 0px)'
                  this.targetIndex = i + 1
                }
              } else {
                this.$refs.imgItem[i].style.transform = 'translate3d(' + (this.clientW) + 'px, 0, 0)'
                this.targetIndex = i
              }
            } else {
              this.targetIndex > this.startIndex && (this.targetIndex = i - 1)
              this.targetIndex < this.startIndex && (this.targetIndex = i + 1)
            }
          }
        }
      }
    },
    touchend (e) {
      this.target.style.transform = 'translate3d(' + (this.targetIndex - this.startIndex) * (this.leftW + this.targetW) + 'px,' + this.targetY + 'px, 0)'
      let start = this.filesResults.splice(this.startIndex, 1)[0]
      this.filesResults.splice(this.targetIndex, 0, start)
      for (let i = 0; i < this.filesResults.length; i++) {
        this.$refs.imgItem[i].style.transform = 'none'
      }
    }
  }
}
</script>
<style lang="less">
  .imageUploaderPage{
    background: #f0f0f3;
    color: #a8a8a8;
    overflow: hidden;
    p{
        text-align: center;
        color: #a7a7a7;
        height: 4.07vw;
        line-height: 4.07vw;
        font-size: var(--mText);
        margin-bottom: var(--nText);
    }
    .imgList{
      padding: 2.78vw 0;
      font-size: 0;
      position: relative;
      .imgCoverItem{
        position: relative;
        width: 23.25vw;
        height: 23.25vw;
        border-radius: 1.11vw;
        display: inline-block;
        vertical-align: top;
        overflow: hidden;
        margin-left: 1.4vw;
        margin-bottom: 1.4vw;
      }
      .upLoadImageWrapper{
        position: relative;
        background: #e0e0e0;
        #upLoadImage{
          position: absolute;
          outline: none;
          z-index: 1;
          top: 0;
          left: 0;
          width: 100%;
          height: 100%;
          opacity: 0;
        }
      }
    }
  }
</style>

 

相关标签: vue 拖拽