Element-UI plus 表格拖拽交换实现

303 阅读1分钟

废话不多说,上代码:

图片.png

js如下:

/**

 * 表格拖拽

 * @param tableData 表格数据

 * @param el 表格元素

 */

const dragTable = {

  el: null as any,

  dragover: null as any,

  drop: null as any,

  dragstart: null as any,

  init(tableData: any[], el: HTMLElement, callback: Function) {

    dragTable.el = el

    const dragover: any = dragTable.dragover = (ev: DragEvent) => {

      ev.preventDefault();

    }

    const drop: any = dragTable.drop = (ev: DragEvent) => {

      ev.preventDefault();

      var index = ev.dataTransfer?.getData("index");

      const path = ev.composedPath();

      const tr = path.find(el => el instanceof HTMLElement && el.tagName === 'TR') as HTMLElement | undefined;

      let end = null, start = index;

      if (tr) {

        const index = tr.dataset.index

        end = index

      }

      if (end !== null && start != end) {

        const _start = parseInt(start || '0')

        const _end = parseInt(end || '0')

        const max = Math.max(_start, _end)

        const min = Math.min(_start, _end)

        const a = tableData.splice(max, 1)

        const b = tableData.splice(min, 1, a[0])

        tableData.splice(max, 0, b[0])

        callback?.({

          start, end

        })

      }

    }

    const dragstart: any = dragTable.dragstart = (ev: DragEvent) => {

      const { index } = ev.target?.dataset

      ev.dataTransfer?.setData("index", index);

    }

  


    const table = el.querySelector('.el-table__body-wrapper')

    const trs = table?.querySelectorAll('tr.el-table__row')

    if (table && trs) {

      table.addEventListener('dragover', dragover, true)

      table.addEventListener('drop', drop, true)

      trs.forEach((tr, index) => {

        tr.setAttribute('draggable', 'true')

        tr.setAttribute('data-index', index + '')

        tr.addEventListener('dragstart', dragstart, true)

      })

    }

  },

  remove() {

    const el = dragTable.el

    const table = el?.querySelector('.el-table__body-wrapper')

    const trs = table?.querySelectorAll('tr.el-table__row')

    if (table && trs) {

      table.removeEventListener('dragover', dragTable.dragover)

      table.removeEventListener('drop', dragTable.drop)

      trs.forEach((tr: HTMLElement) => {

        tr.removeEventListener('dragstart', dragTable.dragstart)

      })

    }

  },

  


}

  


export { dragTable }

使用demo如下:

<template>

  <div class="drag-box" ref="dragBox">

    <el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">

      <el-table-column prop="date" label="Date" width="180" />

      <el-table-column prop="name" label="Name" width="180" />

      <el-table-column prop="address" label="Address" width="360" />

    </el-table>

  </div>

</template>

  


<script lang="ts" setup>

import { ref, onMounted, onUnmounted } from 'vue';

import { dragTable } from '@/utils/utils'

const dragBox = ref<HTMLElement | null>(null)

  


interface User {

  date: string

  name: string

  address: string

}

  


const tableRowClassName = ({

  row,

  rowIndex,

}: {

  row: User

  rowIndex: number

}) => {

  if (rowIndex === 1) {

    return 'warning-row'

  } else if (rowIndex === 3) {

    return 'success-row'

  }

  return ''

}

  


const tableData = ref<User[]>([

  {

    date: '2016-05-01',

    name: '张三',

    address: '四川',

  },

  {

    date: '2016-05-02',

    name: '李四',

    address: '山西',

  },

  {

    date: '2016-05-03',

    name: '王五',

    address: '湖南',

  },

  {

    date: '2016-05-04',

    name: '刘六',

    address: '新疆',

  },

])

onMounted(() => {

  dragTable.init(tableData.value, dragBox.value, (data: any) => {

    console.log(data)

  })

})

onUnmounted(() => {

  dragTable.remove()

})

</script>

  


<style>

.el-table .warning-row {

  --el-table-tr-bg-color: var(--el-color-warning-light-9);

}

  


.el-table .success-row {

  --el-table-tr-bg-color: var(--el-color-success-light-9);

}

</style>