当前位置:   article > 正文

ElementuiPlus的table组件实现行拖动与列拖动_element-plus-table-dragable

element-plus-table-dragable

借助了插件sortablejs。这种方法只适合做非树状table。如果想实现树状table,并且可拖动。可以试一下aggridVue3这个插件

  1. <template>
  2. <div class="draggable" style="padding: 20px">
  3. <el-table row-key="id" :data="tableData" style="width: 100%">
  4. <el-table-column v-for="(item, index) in oldList" :key="`col_${index}`" :prop="newList[index].prop"
  5. :label="item.label" align="center">
  6. </el-table-column>
  7. </el-table>
  8. </div>
  9. </template>
  10. <script setup lang="ts">
  11. import Sortable from 'sortablejs'
  12. import { onMounted, ref } from 'vue'
  13. // 只适合做平级的table行和列拖动
  14. const oldList = ref()
  15. const newList = ref()
  16. // 表头
  17. const tableItems = ref([
  18. {
  19. label: '姓名',
  20. prop: 'name',
  21. },
  22. {
  23. label: '性别',
  24. prop: 'gender',
  25. },
  26. {
  27. label: '年龄',
  28. prop: 'age',
  29. },
  30. ])
  31. // 表体数据
  32. const tableData = ref(
  33. [
  34. {
  35. id: 1,
  36. name: '李四',
  37. gender: '男',
  38. age: 20,
  39. },
  40. {
  41. id: 2,
  42. name: '王五',
  43. gender: '未知',
  44. age: 18,
  45. },
  46. {
  47. id: 3,
  48. name: '张三',
  49. gender: '男',
  50. age: 22,
  51. },
  52. ]
  53. )
  54. // 行拖拽
  55. const rowDrop = function () {
  56. // 要拖拽元素的父容器 tbody
  57. const tbody = document.querySelector('.draggable .el-table__body-wrapper tbody')
  58. Sortable.create(tbody, {
  59. // 可被拖拽的子元素
  60. draggable: ".draggable .el-table__row",
  61. onEnd({ newIndex, oldIndex }) {
  62. // newIndex 拖动到的新的索引
  63. // oldIndex 没拖动前的索引
  64. const currRow = tableData.value.splice(oldIndex, 1)[0]
  65. tableData.value.splice(newIndex, 0, currRow)
  66. }
  67. });
  68. }
  69. // 列拖拽
  70. const columnDrop = function () {
  71. // 要拖拽元素的父容器 头部的tr
  72. const wrapperTr = document.querySelector('.draggable .el-table__header-wrapper tr');
  73. Sortable.create(wrapperTr, {
  74. animation: 180,
  75. delay: 0,
  76. onEnd: (evt: any) => {
  77. const oldItem = newList.value[evt.oldIndex];
  78. newList.value.splice(evt.oldIndex, 1);
  79. newList.value.splice(evt.newIndex, 0, oldItem);
  80. }
  81. })
  82. }
  83. onMounted(() => {
  84. oldList.value = JSON.parse(JSON.stringify(tableItems.value))
  85. newList.value = JSON.parse(JSON.stringify(tableItems.value))
  86. columnDrop()
  87. rowDrop()
  88. })
  89. </script>

效果如下

我试了加操作列,通过el-table-column的默认插槽进行实现,但是列拖动的时候,操作列的内容一直在最后一列,并没有跟着移动

代码如下,如果不需要列拖动的话,可以采取这种方式

  1. <template>
  2. <div class="draggable" style="padding: 20px">
  3. <el-table row-key="id" :data="tableData" style="width: 100%">
  4. <el-table-column v-for="(item, index) in oldList" :key="`col_${index}`"
  5. :label="item.label" align="center">
  6. <template #default="{ row, column, $index }">
  7. <div v-if="column.label !== '操作'">
  8. {{ row[newList[index].prop] }}
  9. </div>
  10. <div v-else>
  11. <el-button size="small">操作</el-button>
  12. </div>
  13. </template>
  14. </el-table-column>
  15. </el-table>
  16. </div>
  17. </template>
  18. <script setup lang="ts">
  19. import Sortable from 'sortablejs'
  20. import { onMounted, ref } from 'vue'
  21. // 只适合做平级的table行和列拖动
  22. const oldList = ref()
  23. const newList = ref()
  24. // 表头
  25. const tableItems = ref([
  26. {
  27. label: '姓名',
  28. prop: 'name',
  29. },
  30. {
  31. label: '性别',
  32. prop: 'gender',
  33. },
  34. {
  35. label: '年龄',
  36. prop: 'age',
  37. },
  38. {
  39. label: '操作',
  40. prop: 'operate',
  41. },
  42. ])
  43. // 表体数据
  44. const tableData = ref(
  45. [
  46. {
  47. id: 1,
  48. name: '李四',
  49. gender: '男',
  50. age: 20,
  51. },
  52. {
  53. id: 2,
  54. name: '王五',
  55. gender: '未知',
  56. age: 18,
  57. },
  58. {
  59. id: 3,
  60. name: '张三',
  61. gender: '男',
  62. age: 22,
  63. },
  64. ]
  65. )
  66. // 行拖拽
  67. const rowDrop = function () {
  68. // 要拖拽元素的父容器 tbody
  69. const tbody = document.querySelector('.draggable .el-table__body-wrapper tbody')
  70. Sortable.create(tbody, {
  71. // 可被拖拽的子元素
  72. draggable: ".draggable .el-table__row",
  73. onEnd({ newIndex, oldIndex }) {
  74. // newIndex 拖动到的新的索引
  75. // oldIndex 没拖动前的索引
  76. const currRow = tableData.value.splice(oldIndex, 1)[0]
  77. tableData.value.splice(newIndex, 0, currRow)
  78. }
  79. });
  80. }
  81. // 列拖拽
  82. const columnDrop = function () {
  83. // 要拖拽元素的父容器 头部的tr
  84. const wrapperTr = document.querySelector('.draggable .el-table__header-wrapper tr');
  85. Sortable.create(wrapperTr, {
  86. animation: 180,
  87. delay: 0,
  88. onEnd: (evt: any) => {
  89. const oldItem = newList.value[evt.oldIndex];
  90. newList.value.splice(evt.oldIndex, 1);
  91. newList.value.splice(evt.newIndex, 0, oldItem);
  92. }
  93. })
  94. }
  95. onMounted(() => {
  96. oldList.value = JSON.parse(JSON.stringify(tableItems.value))
  97. newList.value = JSON.parse(JSON.stringify(tableItems.value))
  98. columnDrop()
  99. rowDrop()
  100. })
  101. </script>

还有一种解决办法就是,把操作放到弹窗操作,比如双击某一行的时候,弹出弹窗,传入这行的数据,在弹窗里面进行操作,这样就不需要添加操作内一列了。行拖动和列拖动也都能使用

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/490216
推荐阅读
相关标签
  

闽ICP备14008679号