vue2+element-表格列自定义组件(拖拽表格)

333 阅读1分钟
<template>
  <div class="draggable" style="height:calc(100vh - 360px);min-height:360px">
    <el-table
      ref="table"
      row-key="CODE"
      :data="tableData"
      style="width: 100%"
      border
      :header-cell-style="{ background: '#F5F7FA' }"
      align="center"
      height="100%"
      highlight-current-row
      stripe
      @header-dragend="()=>{
        $nextTick(() => {
          $refs['table'].doLayout()
        })
      }"
    >
      <el-table-column
        v-for="(item,index) in oldList"
        :key="`col_${index}`"
        :min-width="item.width"
        :prop="newList[index].prop"
        :label="item.label"
        align="center"
      >
        <template slot-scope="scope">
          <span v-if="item.prop==='HIDE'">
            <el-switch v-model="scope.row.hidFlag" />
          </span>
          <span v-else>{{ scope.row[item.prop] }}</span>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
import Sortable from 'sortablejs'

export default {
  props: {
    columns: {
      type: Array,
      default: () => []
    },
    // 是否开启列拖拽
    isColumn: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      oldList: [],
      newList: [],
      tableData: [],
      tableConfig: {
        tableItems: [
          { label: '序号', prop: 'SEQ', width: '80' },
          { label: '编码', prop: 'CODE', width: '120' },
          { label: '名称', prop: 'NAME', width: '120' },
          { label: '是否隐藏', prop: 'HIDE', width: '100  ' }
        ]
      }
    }
  },
  mounted() {
    this.oldList = JSON.parse(JSON.stringify(this.tableConfig.tableItems))
    this.newList = JSON.parse(JSON.stringify(this.tableConfig.tableItems))
    this.tableData = JSON.parse(JSON.stringify(this.columns))
    this.tableData.forEach((el, ind) => {
      el = {
        ...el,
        SEQ: ind + 1,
        hidFlag: el.HIDE === '1'
      }
      this.$set(this.tableData, ind, el)
    })
    this.columnDrop()
    this.rowDrop()
  },
  methods: {
    // 行拖拽
    rowDrop() {
      // 拖拽元素的父盒子
      const tbody = document.querySelector('.draggable .el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        //  指定父元素下可被拖拽的子元素
        draggable: '.draggable .el-table__row',
        onEnd({ newIndex, oldIndex }) {
          const currRow = _this.tableData.splice(oldIndex, 1)[0]
          // 更换顺序
          _this.tableData.splice(newIndex, 0, currRow)
          // 重新排序
          _this.tableData.forEach((el, ind) => { el.SEQ = ind + 1 })
          // 拖拽完成 通知父组件
          _this.$emit('onDraEnd')
        }
      })
    },
    // 列拖拽
    columnDrop() {
      // 未开启列拖拽
      if (!this.isColumn) return
      const wrapperTr = document.querySelector('.draggable .el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: evt => {
          const oldItem = this.newList[evt.oldIndex]
          this.newList.splice(evt.oldIndex, 1)
          this.newList.splice(evt.newIndex, 0, oldItem)
        }
      })
    }
  }
}
</script>
<style scoped  lang="scss">
::v-deep{
  .el-table__row{
    cursor: pointer;
  }
}
</style>