vue用sortablejs实现el-table表格行拖拽排序,在el-dialog中使用遇到的问题

时间:2024-10-01 07:20:51

???? 作者coderYYY
???? 个人简介:前端程序媛,目前主攻web前端,后端辅助,其他技术知识也会偶尔分享????欢迎和我一起交流!????(评论和私信一般会回!!)
???? 个人专栏推荐《前端项目教程以及代码》

✨一、前言

项目中,我们有时需要对表格中的行进行拖拽排序。这种交互方式可以为用户提供更直观、更灵活的数据排序方式。Element UI的el-table组件本身并不支持拖拽排序,但我们可以借助SortableJS这个强大的拖拽库来实现这一功能。

????二、具体实现

????1. 安装和引入依赖

npm install sortablejs --save  
# 或者  
yarn add sortablejs

  • 1
  • 2
  • 3
  • 4

然后,在你的Vue组件中引入Sortable:

import Sortable from 'sortablejs';
  • 1

????2. 在el-table中使用SortableJS

  • el-table添加类 draggable-table
  • 加上 row-key(用来优化 Table 的渲染)
  • 加上row-class-name(把鼠标样式改为拖拽)
<el-table
        row-key="id"
        :data="tableData"
        border
        stripe
        class="draggable-table"
        row-class-name="handle"
      >
      
 </el-table>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

mounted中绑定事件,这种比较适合el-table是直接显示在页面中的

  mounted() {
      const tbody = document.querySelector('.draggable-table .el-table__body-wrapper tbody')
      new Sortable(tbody, {
        handle: '.handle', // handle's class
        animation: 150,
        // 需要在odEnd方法中处理原始eltable数据,使原始数据与显示数据保持顺序一致
        onEnd: ({ newIndex, oldIndex }) => {
          const targetRow = this.tableData[oldIndex]
          this.tableData.splice(oldIndex, 1)
          this.tableData.splice(newIndex, 0, targetRow)
          console.table(this.tableData)
        },
      })
    },
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
.handle {
  cursor: move;
}
::v-deep .el-table--enable-row-hover .el-table__body tr:hover > td {
  cursor: move;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

但是如果是点击按钮后出现表格弹窗排序,上面的方法是获取不到元素的,要用下面这种方法:

 <el-button
          type="success"
          plain
          icon="el-icon-sort"
          size="mini"
          @click="handleSort"
          >排序</el-button
        >
    <el-dialog
      title="拖拽排序"
      :="open"
      width="1000px"
      append-to-body
    >
      <el-table
        row-key="id"
    
        :data="sortData"
        border
        stripe
        class="draggable-table"
        style="width: 100%"
        row-class-name="handle"
      >
    <!-- 表格内容.... -->
   
      </el-table>
      <span slot="footer" class="dialog-footer">
        <el-button @click="cancel">取 消</el-button>
        <el-button :loading="buttonLoading" type="primary" @click="submitSort"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

重点: document.body.querySelector、this.$nextTick

/* 排序 */
    handleSort() {
      this.open = true;
      this.$nextTick(() => {
        const tbody = document.body.querySelector(
          ".draggable-table .el-table__body-wrapper tbody"
        );
        if (tbody) {
          new Sortable(tbody, {
            handle: ".handle", // handle's class
            animation: 150,
            // 需要在odEnd方法中处理原始eltable数据,使原始数据与显示数据保持顺序一致
            onEnd: ({ newIndex, oldIndex }) => {
              const targetRow = this.sortData[oldIndex];
              this.sortData.splice(oldIndex, 1);
              this.sortData.splice(newIndex, 0, targetRow);
              console.table(this.sortData);
            },
          });
        } else {
          console.error("未能找到可排序的表格元素");
        }
      });
    },
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

????三、总结

在这个示例中,我们首先通过querySelector('.el-table__body-wrapper tbody')获取到el-table的tbody元素,然后使用new Sortable方法在这个元素上创建一个Sortable实例。onEnd回调会在拖拽结束后触发,我们可以在这个回调中更新tableData数组的顺序,以反映用户通过拖拽所做的更改,重点是元素的获取要正确