vue2 使用 sortablejs 拖拽案例

548 阅读2分钟
<template>
  <div id="app">

    <!-- 左侧内容 -->
    <div class="Drag-Box">
      <div class="title">拖拽demo</div>
      <div class="Drag-Box-container scrollBox" id="Drag-Box-container">
        <div v-for="(item,ids) in 88" :key="ids" class="Drag-Box-item" 
          @dragstart="getCoordinate" @drag="getPageCoord">
          {{ item }}
        </div>
      </div>
    </div>

    <!-- 右侧内容 -->
    <div class="Drag-container">
      <div class="title">展示demo</div>
      <div class="Drag-unfold scrollBox" id="Drag-unfold">
        <div class="Drag-Box-item"
          @dragstart="getCoordinate"
          @drag="getPageCoord"
          :id="`${ids}`"
          :style="{ 'position': 'absolute', 'margin': '0px', top: item.clientY + 'px', left: item.clientX + 'px' }"
           v-for="(item,ids) in DropData" :key="item.id">

            {{ item.text }}

          <i @click.stop="delDemo(item,ids)"  class="el-icon-delete"></i>
        </div>
      </div>
    </div>

  </div>
</template>

<script>
import { v4 as uuidv4 } from 'uuid';
import Sortable from 'sortablejs';
export default {
  data() {
    return {
      isDisabled: false,
      X: '',
      Y: '',
      pageX: '',
      pageY: '',
      offsetX: '',
      offsetY: '',
      DropData: []
    }
  },
  mounted() {
    this.initLeftDrop()
    this.initRightDrop()
  },
  methods: {
    getClientRect() {
      return {
        left: document.querySelector("#Drag-unfold").getBoundingClientRect().left,
        top: document.querySelector("#Drag-unfold").getBoundingClientRect().top
      }
    },
    //获取鼠标相对于拖拽盒子的位置
    getCoordinate(e) {
      this.offsetY = e.offsetY <= 0 ? 0 : e.offsetY
      this.offsetX = e.offsetX <= 0 ? 0 : e.offsetX
    },
    getPageCoord(e) {
      let { left, top }  = this.getClientRect()
      this.pageX = e.pageX <= 0 ? 0 : e.pageX
      this.pageY = e.pageY <= 0 ? 0 : e.pageY

      if(this.pageX == 0 && this.pageY == 0) {
        this.isDisabled = true
      } else {
        this.isDisabled = false
      }

      this.X = this.pageX - this.offsetX - left
      this.Y = this.pageY - this.offsetY - top + document.querySelector('#Drag-unfold').scrollTop
    },
    delDemo(val,index) {
      this.DropData.splice(index, 1)
    },
    initLeftDrop() {
      let that = this
      const ref = document.querySelector("#Drag-Box-container");
      const sorttable = Sortable.create(ref, {
        animation: 180,
        sort: false,   // boolean 定义是否列表单元是否可以在列表容器内进行拖拽排序
        group: {
          name: 'Drag-Box-container',
          pull: 'clone',
          put: false 
        },
        // 开始拖拽的时候
        onStart: function (evt) {},
        //结束拖拽
        onEnd(evt) {
          if(evt.originalEvent.srcElement.className.includes('Drag-unfold')) {
            let DropObj = {}
            DropObj.id = uuidv4()
            DropObj.clientY = that.Y <= 0 ? 0 : that.Y
            DropObj.clientX = that.X <= 0 ? 0 : that.X
            DropObj.text = evt.item.textContent
            that.DropData.push(DropObj)
          }
        },
      });
    },
    initRightDrop() {
      let that = this
      const ref = document.querySelector("#Drag-unfold");
      const sorttable = Sortable.create(ref, {
        animation: 180,
        group: {
          name: 'Drag-unfold',
          pull: 'clone',
        },
        // 开始拖拽的时候
        onStart: function (evt) {},
        //结束拖拽
        onEnd(evt) {
          if(!that.isDisabled) {
            that.DropData.forEach((item, index)=> {
              if(evt.item.getAttribute('id') == index) {
                item.clientY =  that.Y <= 0 ? 0 : that.Y
                item.clientX =  that.X <= 0 ? 0 : that.X 
              }
            })
          }
        },
      });
    }
  }
}
</script>

<style lang="scss">
html,body {
  height: 100%;
  margin: 0px;
  padding: 0px;
}
#app {
  overflow: hidden;
  height: 100%;
  display: flex;
  background-color: #fcfcfc;
  .title {
    height: 40px;
    line-height: 40px;
    text-align: center;
    border-bottom: 1px solid #0505050f;
  }
  .scrollBox::-webkit-scrollbar {
    -webkit-appearance: none;
    width: 6px;
    height: 6px;
  }

  .scrollBox::-webkit-scrollbar-track {
    background: rgba(0, 0, 0, 0.1);
    border-radius: 0;
  }

  .scrollBox::-webkit-scrollbar-thumb {
    cursor: pointer;
    border-radius: 5px;
    background: rgba(0, 0, 0, 0.15);
    transition: color 0.2s ease;
  }

  .scrollBox::-webkit-scrollbar-thumb:hover {
    background: rgba(0, 0, 0, 0.3);
  }
  .Drag-Box-item {
    padding: 0px 10px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    margin: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    cursor: pointer;
    &:hover {
      border-color: rgb(24, 144, 255);
    }
    .el-icon-delete {
        &:hover {
        color: red;
      }
    }
  }
  .Drag-Box {
    width: 300px;
    margin-right: 20px;
    background: #ffffff;
    border: 1px solid #0505050f;
    border-top: none;
    .Drag-Box-container {
      height: calc(100vh - 41px);
      overflow-y: auto;
      display: flex;
      flex-wrap: wrap;
    }
  }
  .Drag-container {
    flex: 1;
    height: 100%;
    background: #ffffff;
    border: 1px solid #0505050f;
    border-top: none;
    .Drag-unfold {
      position: relative;
      height: calc(100vh - 41px);
      overflow-y: auto;
    }
  }
}
</style>