目标

vue项目中实现一个可拖拽的Table组件,并保存拖拽后的顺序

安装Sortable

$ npm install sortablejs --save

代码实现

创建DragableTable.vue文件,定义templateprops

<template>
  <div>
    <Table
      ref="table" :columns="columns" :data="data" highlight-row border>
    </Table>
  </div>
</template>

<script>

  export default {
    name: 'DragableTable',
    props: {
      columns: Array,
      data: Array
    },
    data() {
      return {
      }
    }
  };
</script>

引入依赖

import Sortable from 'sortablejs';

定义table对象

   data() {
      return {
        table: {
          isDragging: false, // 是否正在被拖拽
          oldIndex: 0, // 原索引
          newIndex: 0, // 新索引
          draggingRecord: [] // 拖拽记录
        }
      }
    }

ref定位排序容器,Sortable.create初始化可排序对象,绑定onStartonEnd事件

Sortable.create('id_of_container',[options]);

    mounted() {
      var el = this.$refs.table.$children[1].$el.children[1];
      let vm = this;
      Sortable.create(el, {
        onStart: vm.handleOnstart,
        onEnd: vm.handleOnend
      });
    }

定义handleOnStarthandleOnEnd方法,并抛出on-drag-change事件

      handleOnstart(el) {
        this.table.oldIndex = el.oldIndex;
        this.table.isDragging = true;
      },
      handleOnend(el) {
        this.table.newIndex = el.newIndex;
        this.table.isDragging = false;
        this.table.draggingRecord.unshift({
          from: this.table.oldIndex,
          to: this.table.newIndex
        });
        this.$emit('on-drag-change', el.oldIndex, el.newIndex);
      }

拖拽Table组件基本完成

使用

引入DragableTable组件并注册

import dragTable from '@/components/dragTable';
export default {
    components: {
      dragTable
    }
}

定义DOM

<drag-table ref="table" :columns="columns" :data="tableData"
            border :height="height"
            @on-drag-change="dragChange">
</drag-table>

实现dragChange方法

tableData中已有numbers属性表示行数据的索引位置,我们需要计算移动行的newNumbers,即新的位置

由于numbers字段在库中是以1开始的,如果要按0开始需要修改下面的代码

      /**
       * 拖拽排序
       * @param oldIndex 拖拽原索引 newIndex 拖拽目标索引
       */
      dragChange(oldIndex, newIndex) {
        let data = this.tableData;
        for (let i = 0; i < data.length; i++) {
          // 原索引小于目标索引时,中间数据前移一位,原索引移到目标索引
          if (oldIndex < newIndex) {
            if (i < oldIndex || i > newIndex) {
              data[i].newNumbers = i + 1;
            } else if (i === oldIndex) {
              data[i].newNumbers = newIndex + 1;
            } else {
              data[i].newNumbers = i;
            }
          } else {
            // 原索引大于目标索引时,中间数据后移一位,原索引移到目标索引
            if (i < newIndex || i > oldIndex) {
              data[i].newNumbers = i + 1;
            } else if (i === oldIndex) {
              data[i].newNumbers = newIndex + 1;
            } else {
              data[i].newNumbers = i + 2;
            }
          }
        }
        // 根据newNumbers判断行数据是否被移动,若移动刷新数组数据
        let _tableData = [];
        for (let j = 0; j < data.length; j++) {
          _tableData[data[j].newNumbers - 1] = data[j];
        }
        this.tableData = _tableData;
      },

最后,我们发送请求,将移动过的行数据的newNumbers替换numbers,存入库中即可

Logo

前往低代码交流专区

更多推荐