vue+element-ui+sortable.js实现表格行和列的拖拽

项目碰到一个需求是需要表格字段列进行顺序拖拽,查过一些资料,中途也碰到了很多坑,实现方式如下:

封装成公用组件操作

//父组件
<template>
   <div>
      <commonTable
        :loading="loading"
        :table-data="priceList"
        :table-header-tit="tableHeaderTit"
        :col-table-header-tit="colTableHeaderTit"
        @columnChange="columnChange"
      />
   </div>
</template>
<script>
import commonTable from '@/layout/components/common/commonTable.vue';
export default {
  name: 'Table',
  components: {
    commonTable
  },
  data() {
     tableHeaderTit: [],
     colTableHeaderTit:[],
     priceList:[],
     loading:false,
   },
   async mounted() {
      await this.initHandle();
   },
  methods:{
      initHandle(){
         //初始化调用获取默认用户表头数据接口(这边先用默认数据)
          this.tableHeaderTit=[
              { key: 1, label: '价单编号', field: 'priceCode'},
        { key: 2, label: '价单名称', field: 'priceName' },
        { key: 3, label: '币种', field: 'currency' },
        { key: 4, label: '业务类型', field: 'businessTypeName'},
        { key: 5, label: '审批状态', field: 'auditStatusName'},
        { key: 6, label: '启用日期', field: 'startDate' },
        { key: 7, label: '截止日期', field: 'endDate'}
          ];
          this.colTableHeaderTit=[
               { key: 1, label: '价单编号', field: 'priceCode'},
        { key: 2, label: '价单名称', field: 'priceName' },
        { key: 3, label: '币种', field: 'currency' },
        { key: 4, label: '业务类型', field: 'businessTypeName'},
        { key: 5, label: '审批状态', field: 'auditStatusName'},
        { key: 6, label: '启用日期', field: 'startDate' },
        { key: 7, label: '截止日期', field: 'endDate'}
          ]
      },
      columnChange(val) {
        // 列拖拽操作(改变一次排序远程存储一次用户数据)
        //调保存用户接口
      }
  }
}
</script>
//子组件  commonTable.vue
<template>
  <div class="commonTable">
    <el-table
          ref="table"
          v-loading="loading"
          style="width: 100%"
          class="table-wrap"
          :data="tableData"
          height="100%"
          row-key="item"
          stripe
          border
          header-cell-class-name="header-cell-color"
          @selection-change="handleSelectionChange"
        >
        <el-table-column
            type="selection"
            width="55"
          />
        <el-table-column v-for="(item, index) in colTableHeaderTit"
            class-name="allowDrag"
            :key="`colTableHeaderTit_${index}`"
            :prop="tableHeaderTit[index].field"
            :label="item.label" align="center"> 
        </el-table-column>
    </el-table>
  </div>
</template>
<script>
import Sortable from 'sortablejs' 
//需要下载sortablejs插件
//官方文档地址:
https://github.com/SortableJS/Sortable export default { name:'commonTable', props:['tableData','tableHeaderTit','colTableHeaderTit','loading'], data() { return { } }, mounted() { this.rowDrop() //可拖拽行 this.columnDrop() //可拖拽列 }, methods: { //行拖拽 rowDrop() { const tbody = document.querySelector('.el-table__body-wrapper tbody') const _this = this Sortable.create(tbody, { onEnd({ newIndex, oldIndex }) { const currRow = _this.tableData.splice(oldIndex, 1)[0] _this.tableData.splice(newIndex, 0, currRow) } }) }, //列拖拽 columnDrop() { var _this = this; const wrapperTr = document.querySelector('.el-table__header-wrapper tr') this.sortable = Sortable.create(wrapperTr, { draggable: ".allowDrag",//允许拖拽元素(el-table-column上设置class-name为允许拖拽) animation: 180, delay: 0, //之前调用onEnd方法会出现表格DOM不更新以及表头对不上的情况所以更换为onUpdate方法 //参考资料 https://www.jianshu.com/p/fd6eb408d8bd onUpdate:function(evt){ //修改items数据顺序 var newIndex = evt.newIndex; var oldIndex = evt.oldIndex; const newItem = wrapperTr.children[newIndex]; const oldItem = wrapperTr.children[oldIndex]; // 先删除移动的节点 wrapperTr.removeChild(newItem) // 再插入移动的节点到原有节点,还原了移动的操作 if(newIndex > oldIndex) { wrapperTr.insertBefore(newItem,oldItem) } else { wrapperTr.insertBefore(newItem,oldItem.nextSibling) } // 更新items数组(index-1是第一列有一个多选列不支持拖拽,否则会有排序错乱的问题) var item = _this.tableHeaderTit.splice(oldIndex-1,1); _this.tableHeaderTit.splice(newIndex-1,0,item[0]); // 下一个tick就会走patch更新 //每次更新调取保存用户接口 _this.$emit('columnChange',_this.tableHeaderTit) } }) } } } </script>

参考:https://www.jianshu.com/p/362f880d0bfd 

 

-----END

 

posted @ 2022-01-18 16:28  陪伴者  阅读(1992)  评论(0编辑  收藏  举报