vue开发:原生拖拽列表,更换元素位置。下面是代码:

拖拽Api

方法名释义
ondraggable设置元素是否允许被拖动。链接和图片默认是可拖动,因此不用设置该属性
ondragstart用户开始拖动元素或选择的文本时触发。
ondragover1.拖动元素或选取的文本正在拖动到放置目标时触发。2.默认情况下,数据/元素不能放置到其他元素中。3.如果要实现改功能,我们需要防止元素的默认处理方法。4.我们可以通过调用event.preventDefault()方法来实现 ondragover 事件。
ondragenter当被鼠标拖动的对象进入其容器范围内时触发此事件
ondragend用户完成元素拖动后触发
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title>原生拖拽列表,更换元素位置</title>
  <!--引入 element-ui 的样式,-->
  <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
  <script src="https://cdn.bootcss.com/vue/2.5.16/vue.min.js"></script>
  <!-- 引入element 的组件库-->
  <script src="https://unpkg.com/element-ui/lib/index.js"></script>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    #app {
      margin: 50px;
    }

    .item {
      border: 1px solid #000;
      margin: 10px;
      padding: 10px;
    }
  </style>
</head>

<body>
  <div id="app">
    <div v-for="(item, index) in summaryArr" :key="index" draggable="true" @click.stop="orientationFun(item)"
      @dragstart.stop="handleDragStart($event, item)" @dragover.prevent.stop="handleDragOver($event, item)"
      @dragenter.stop="handleDragEnter($event, item)" @dragend.stop="handleDragEnd($event, item)" class="item">
      {{item.text}}
    </div>
  </div>
  <script>
    new Vue({
      el: '#app',
      data() {
        return {
          // 源数据
          summaryArr: [
            {
              id: '1',
              text: '内容1'
            },
            {
              id: '2',
              text: '内容2'
            },
            {
              id: '3',
              text: '内容3'
            },
            {
              id: '4',
              text: '内容4'
            },
            {
              id: '5',
              text: '内容5'
            }
          ],
          // 深拷贝源数据
          summaryArrCopy: [],
          dragging: null,

        }
      },
      created() {
        // 深拷贝最新的源数据,目的是为了判断拖拽的位置是否有没有更换,没有更换就不调接口
        this.summaryArrCopy = JSON.parse(JSON.stringify(this.summaryArr));
      },
      methods: {
        handleDragStart(e, items) {
          // 开始拖动时,暂时保存当前拖动的数据。
          this.dragging = items;
        },
        handleDragEnd(e, items) {
          // 是否更换过位置,如果拖拽过后还是原位置,则不调取接口
          const isChangePosition = this.summaryArr.some((item, index) => {
            if (item.id === this.summaryArrCopy[index].id) {
              return false;
            } else {
              return true;
            }
          });
          this.dragging = null;
          if (isChangePosition) {
            // 深拷贝最新的源数据,目的是为了判断拖拽的位置是否有没有更换,没有更换就不调接口
            this.summaryArrCopy = JSON.parse(JSON.stringify(this.summaryArr));
            // 调取接口
            console.log(this.summaryArr, '排序过后的数据')
            this.$message({
              message: '排序成功!',
              type: 'success'
            });

          }
        },
        handleDragOver(e) {
          // 在dragenter中针对放置目标来设置!
          e.dataTransfer.dropEffect = "move";
        },
        handleDragEnter(e, items) {
          // 为需要移动的元素设置dragstart事件
          e.dataTransfer.effectAllowed = "move";
          if (items == this.dragging) return;
          // 拷贝一份数据进行交换操作。
          var newItems = [...this.summaryArr];
          // 获取数组下标
          var src = newItems.indexOf(this.dragging);
          var dst = newItems.indexOf(items);
          // 交换位置
          newItems.splice(dst, 0, ...newItems.splice(src, 1));
          this.summaryArr = newItems;


        },

      }
    })
  </script>

</body>

</html>

效果:
image.png
代码里面做了一个小优化:深拷贝最新的源数据,目的是判断是否更换过位置,如果拖拽过后还是原位置,则不调取接口


我的一个道姑朋友
80 声望4 粉丝

星光不问赶路人,岁月不负有心人。