element-ui table+sortable.js表格排序

627 阅读1分钟

支持树形数据拖拽

<template>
  <div class="tablePage">
    <el-table class="drag"
      :data="localTableData"
      style="width: 100%;margin-bottom: 20px;"
      row-key="name"
      border
      default-expand-all
      :indent="0"
      :tree-props="{children: 'subRoutes', hasChildren: 'hasChildren'}">
      <el-table-column v-for="item in columns" :key="item" :prop="item.prop" :label="item.label"></el-table-column>
    </el-table>
  </div>
</template>

<script>
  import Sortable from 'sortable.js'

  export default {
    props:{
      tableData: {
        type: Array,
        default: ()=>[]
      },
    },
    data() {
      return {
        copyTableData:[],
        localTableData: [],
        newTableArr:[],
        sortable:null,
        columns: [
          { prop: ''},
          { prop: 'matcherPath', label: '匹配值'},
          { prop: 'matcherType', label: '匹配类型'},
          { label: '目标服务'},
          { prop: 'desc', label: '描述'},
          { prop: 'publishStatus', label: '发布状态'},
          { prop: 'modifyTime', label: '最后修改' }
        ]
      }
    },
    watch:{
      tableData(){
        this.newTableArr=[]
        this.localTableData = Object.assign([], this.transformDatas(this.tableData));
        this.copyTableData = Object.assign([], this.localTableData);
      }
    },
    mounted() {
      this.$nextTick(() => {
        this.rowDrop()
      })
    },
    methods: {
      transformDatas(datas,parentMath) {
        datas.forEach(item => {
          item.parentMath = parentMath
          this.newTableArr.push(item)
          if(item.subRoutes && item.subRoutes.length > 0) {
            this.transformDatas(item.subRoutes, item.matcherPath)
          }
        })
        return datas
      },
      buildTree(list) {
        let dataArray = []
        let otherList = []
        list.forEach(item => {
          if(!item.paths){
            dataArray.push(item)
          }else{
            otherList.push(item)
          }
        });
        return this.updateChildren(otherList, dataArray)
      },
      updateChildren(datas, dataArray) {
        dataArray.forEach(item => {
          if(item.subRoutes && item.subRoutes.length > 0) {
            let childrenArray = []
            let parentTable = item.name
            datas.forEach(innerItem => {
              if(parentTable === innerItem.parentTable) {
                childrenArray.push(innerItem)
              }
            })
            item.subRoutes= childrenArray
            this.updateChildren(datas, childrenArray)
          }
        })
        return dataArray
      },
      rowDrop() {
        const tbody = document.querySelector('.drag .el-table__body-wrapper tbody');
        const _this = this;
        _this.sortable = Sortable.create(tbody, {
          onEnd({ newIndex, oldIndex }) {
            //以下为前端逻辑处理拖拽
            const sourceObj = _this.newTableArr[oldIndex]; 
            const targetObj = _this.newTableArr[newIndex];
            // 判断是否为同级
            if (sourceObj.parentTable === targetObj.parentTable) {
              const currRow = _this.newTableArr.splice(oldIndex, 1)[0];
              _this.newTableArr.splice(newIndex, 0, currRow);
              let endTable = _this.buildTree(_this.newTableArr) //将扁平数组换为树
              _this.localTableData = endTable;
              _this.copyTableData = endTable;
              //带子项的就是多条数据移动
              if((sourceObj.subRoutes&&sourceObj.subRoutes.length > 0)
                ||(targetObj.subRoutes&&targetObj.subRoutes.length > 0)){
                _this.newTableArr= []
                _this.transformDatas(_this.localTableData)
              }
            }else{
              _this.$message.warning('只能在同级之间进行拖拽排序');
              _this.$set(_this, 'localTableData', []);
              // 重新渲染表格
              _this.$nextTick(() => {
                _this.$set(_this, 'localTableData', _this.copyTableData);
              });
            }
          },
        });
      },
    }
  }
</script>
<style>
  .grayColor{
    color: #cecece;
  }
  .hasSpace{
    padding-right: 8px;
  }
  .routeCircle{
    height: 10px;
    width: 10px;
    border-radius: 50%;
    display: inline-block;
  }
  .Publish {
    background-color: #87d068;
  }
  .Offline {
    background-color: #929292;
  }
  .UnPublish {
    background-color: #D5D5D6;
  }
  .sortable-ghost{
    opacity: .8;
    color: #fff!important;
    background: #42b983!important;
  }
  .handleFlag{
    cursor: all-scroll;
  }
</style>