likes
comments
collection
share

ElementUI和sortable.js实现表格行列拖动

作者站长头像
站长
· 阅读数 36

直接上代码:

<template>
  <div style="padding:15px;">
    <h3 style="text-align: left; padding:10px; background: #ccc;">
      vue+element-ui+sortable.js表格行和列拖拽
    </h3>
    <div style="width: 55%; margin-right:4%; float: left;">
      <el-table :data="tableData"
                border
                row-key="id"
                align="left"
                @cell-click="cellClick">
        <el-table-column type="selection" align="center"></el-table-column>
        <el-table-column
          v-for="(item, index) in colList"
          :key="index"
          :prop="item.prop"
          :label="item.label"
          class-name="move"
          align="center">
            <!--核心代码: 让列内容跟着列头调整-->
            <template slot-scope="scope">
              <p>{{ scope.row[dropCol[index].prop] }}</p>
            </template>
        </el-table-column>
      </el-table>
    </div>
    <div style="width: 40%; float: left; border:1px solid #ccc;">
            <pre style="text-align: left">
                {{dropCol}}
            </pre>
      <hr>
      <pre style="text-align: left">
                {{tableData}}
            </pre>
    </div>
  </div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
  filters:{
    valueFilter(value,row){
      console.log('value:',value,row);
      return row[value];
    }
  },
  data() {
    return {
      colList: [
        // 序号
        {
          type: 'index',
          label: '序号',
          prop: 'id'
        },
        {
          label: '日期',
          prop: 'date'
        },
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'address'
        }
      ],
      dropCol: [
        // 序号
        {
          type: 'index',
          label: '序号',
          prop: 'id'
        },
        {
          label: '日期',
          prop: 'date'
        },
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'address'
        }
      ],
      tableData: [
        {
          id:'1',
          date: '2016-05-02',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 188 弄',
          edit: false
        },
        {
          id:'2',
          date: '2016-05-09',
          name: '王小虎2',
          address: '上海市普陀区金沙江路 100 弄',
          edit: true
        },
        {
          id:'3',
          date: '2016-07-03',
          name: '王小虎3',
          address: '上海市普陀区金沙江路 233 弄',
          edit: false
        },
        {
          id:'4',
          date: '2020-04-28',
          name: '王小虎4',
          address: '上海市普陀区金沙江路 56 弄',
          edit: false
        }
      ]
    }
  },
  mounted() {
    this.rowDrop()
    this.columnDrop()
  },
  methods: {
    cellClick(row, column, cell, event){
      console.log('cellClick:',row, column, cell, event)
    },
    //行拖拽
    rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          console.log('onEnd:',newIndex, oldIndex)
          const currRow = _this.tableData.splice(oldIndex, 1)[0]
          _this.tableData.splice(newIndex, 0, currRow)
        }
      })
    },
    //列拖拽
    columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr');
      console.log('wrapperTr:',wrapperTr)
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        handle: '.move', // 只有带move类名的元素才能拖动,多选框禁止拖动
        onEnd: evt => {
          // 因为手动加了一个多选框, 不在表头循环数组内, 所以这里减1
          let oldIndx = evt.oldIndex - 1;
          let newIndx = evt.newIndex - 1;
          const oldItem = this.dropCol[oldIndx]
          // 真正改变列数据--变化列头,就能实现列拖动 列数据按列头索引取值 {{ scope.row[dropCol[index].prop] }}
          this.dropCol.splice(oldIndx, 1) // 删除旧一行 删除为1
          this.dropCol.splice(newIndx, 0, oldItem) // 插入新一行 插入为0
        }
      })
    }
  }
}
</script>
<style scoped>
</style>