前端elementui表格拖拽sortablejs避坑,vue2前端表格列拖拽解决方案

sortablejs

sortablejs是目前比较多人用的elementui表格拖拽的插件,但是这个插件的bug很不友好:主要bug是拖拽列后不能调整列的宽,处理这个bug只能是不让用户调整列宽。

这里还是简单介绍下sortablejs的使用吧,然后再介绍一个很好用的表格插件GridManager。

1、首先下载 sortablejs

npm install sortablejs

2、在需要使用拖拽的页面进行使用


<template>
    <div>
      <el-table :data="studentInfoList"
      ref="dropTable"
      border
      row-key="infoId">

        <el-table-column
        align="center"
        v-for="(item, index) in col"
          sortable 
          :key="`col_${index}`"
          :resizable="false"
          :width="item.width?item.width:120"
          :prop="dropCol[index].prop?dropCol[index].prop:''"
          :type="item.type?item.type:''"
          :label="item.label?item.label:''"
        >
          
        </el-table-column>

      </el-table>
    </div>
</template>

<script>
//引入sortablejs
import Sortable from 'sortablejs'
export default {
  components: {},
  data() {
    return {
      studentInfoList:[
        {
          name:'华为',
          age:14,
          high:'183'
        },
        {
          name:'小米',
          age:58,
          high:'168'
        },
        {
          name:'苹果',
          age:20,
          high:'170'
        }
      ],
      //动态列数组
      col: [
        {
          type: 'selection',
          width: 60
        },
        {
          label: "名字",
          prop: "name",
        },
        {
          label: "年龄",
          prop: "age",
        },
        {
          label: "身高",
          prop: "high",
        },
      ],
      //拖拽列
      dropCol:[
      {
          type: 'selection',
          width: 60
        },
        {
          label: "名字",
          prop: "name",
        },
        {
          label: "年龄",
          prop: "age",
        },
        {
          label: "身高",
          prop: "high",
        },
      ]
    };
  },
  computed: {},
  created() {
  
  },
  mounted() {
    this.columnDrop();
  },
  methods: {
    // sortable初始化
    InitializeSortable() {
      const sortableId = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(sortableId, {
        // 元素被选中
        onChoose: function (/**Event*/evt) {
            evt.oldIndex;  // element index widthin parent
        },
        // 开始拖拽的时候
        onStart: function (/**Event*/evt) {
            evt.oldIndex;  // element index widthin parent
        },
        // 结束拖拽
        onEnd: function (/**Event*/evt) {
            var itemEl = evt.item;  // dragged HTMLElement
            evt.to;    // target list
            evt.from;  // previous list
            evt.oldIndex;  // element's old index widthin old parent
            evt.newIndex;  // element's new index widthin new parent
            evt.clone // the clone element
            evt.pullMode;  // when item is in another sortable: `"clone"` if cloning, `true` if moving
        },
        // 元素从一个列表拖拽到另一个列表
        onAdd: function (/**Event*/evt) {
            // same properties as onEnd
        },
        // 列表内元素顺序更新的时候触发
        onUpdate: function (/**Event*/evt) {
            // same properties as onEnd
        },
        // 列表的任何更改都会触发
        onSort: function (/**Event*/evt) {
            // same properties as onEnd
        },
        // 元素从列表中移除进入另一个列表
        onRemove: function (/**Event*/evt) {
            // same properties as onEnd
        },
        // 试图拖拽一个filtered的元素
        onFilter: function (/**Event*/evt) {
            var itemEl = evt.item;  // HTMLElement receiving the `mousedown|tapstart` event.
        },
        // 拖拽移动的时候
        onMove: function (/**Event*/evt, /**Event*/originalEvent) {
            // Example: https://jsbin.com/nawahef/edit?js,output
            evt.dragged; // dragged HTMLElement
            evt.draggedRect; // DOMRect {left, top, right, bottom}
            evt.related; // HTMLElement on which have guided
            evt.relatedRect; // DOMRect
            evt.willInsertAfter; // Boolean that is true if Sortable will insert drag element after target by default
            originalEvent.clientY; // mouse position
            // return false;for cancel
            // return -1; — insert before target
            // return 1; — insert after target
        },
        // clone一个元素的时候触发
        onClone: function (/**Event*/evt) {
            var origEl = evt.item;
            var cloneEl = evt.clone;
        },
        // 拖拽元素改变位置的时候
        onChange: function(/**Event*/evt) {
            evt.newIndex // most likely why this event is used is to get the dragging element's current index
            // same properties as onEnd
        }
      })
    },
  //列拖拽
  columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: evt => {
          const oldItem = this.dropCol[evt.oldIndex]
          this.dropCol.splice(evt.oldIndex, 1)
          this.dropCol.splice(evt.newIndex, 0, oldItem)
          this.InitializeSortable()
        }
      })
    },
  },
  destroyed() {}
}