table表格拖拽


el-table 的拖拽使用 Sortable.js
官方文档 :https://github.com/SortableJS/Sortable

1. 通过 npm 使用 sortable

//安装sortablejs
npm install sortablejs --save

//引用 sorttablejs
import Sortable from 'sortablejs'

2.用法

SorRow() {
   // 获取表格row的父节点
    const tbody = this.$refs.table.$el.querySelector( ".el-table__body-wrapper tbody");
   // 创建行拖拽实例
   const dragTableRow = Sortable.create(tbody, {
     animation: 150, //动画
     handle: ".move", //指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽)
     filter: ".disabled", //指定不可拖动的类名(el-table中可通过row-class-name设置行的class)
     dragClass: "dragClass", //设置拖拽样式类名
     ghostClass: "ghostClass", //设置拖拽停靠样式类名
     chosenClass: "chosenClass", //设置选中样式类名
     // 开始拖动事件
     onStart: () => {
       console.log("开始拖动");
     },
     // 结束拖动事件
     onEnd: (e) => {
       console.log(
         "结束拖动",
         `拖动前索引${e.oldIndex}---拖动后索引${e.newIndex}`
       );
     },
   });
 },
 // 列拖拽
 SorCol() {
   //获取表格col的父节点
   const eleCol = this.$refs.table.$el.querySelector(".el-table__header-wrapper tr");
   // 创建列拖拽实例
   const dragTableCol = Sortable.create(eleCol, {
     animation: 150,
     dragClass: "dragClass",
     ghostClass: "ghostClass",
     chosenClass: "chosenClass",
     // 结束拖动事件
     onEnd: (e) => {
       // 拖拽结束之后通过修改tableHeaderData顺序改变表头顺序
       const dragHeaderCopy = this.tableHeaderData[e.oldIndex]; // 备份当前拖拽的表头
       this.tableHeaderData.splice(e.oldIndex, 1); //把当前拖动的表头去掉
       this.tableHeaderData.splice(e.newIndex, 0, dragHeaderCopy); //把当前拖拽的表头添加到新位置
       /**
           * 在做列拖拽功能时发现问题:表头位置错乱,但是内容列正常
           * 于是我给el-table绑定key,每次拖拽结束改变key触发表格重新渲染。
           * 但引出新的问题:表格重渲拖拽事件丢失,导致之后无法拖拽
           * 于是我在表格重渲之后重新调用拖拽方法创建拖拽实例,功能正常
           * **/
       this.key += 1;
       this.$nextTick(() => {
         this.SorRow();
         this.SorCol();
       });
       console.log(dragHeaderCopy, "结束拖动", this.tableHeaderData);
     },
   });
 },
 // 设置表格row的class(此例中通过设置class来配合拖拽属性filter设置某行不可拖拽)
 tableRowClassName({ row }) {
   if (row.disabled) {
     return "disabled";
   }
   return "";
 },

 <style lang='scss'>
// 拖拽
.dragClass {
  background: rgba($color: #41c21a, $alpha: 0.5) !important;
}
// 停靠
.ghostClass {
  background: rgba($color: #6cacf5, $alpha: 0.5) !important;
}
// 选择
.chosenClass:hover > td {
  background: rgba($color: #f56c6c, $alpha: 0.5) !important;
}
</style>

3.实际使用

<template>
  <div class="container">
    <el-table
      :data="tableData"
      ref="table"
      row-key="roleId"
      @cell-mouse-enter.once="eventDrag"
      border
      size="small"
    >
      <el-table-column prop="sort" label="拖拽区域">
        <template>
          <el-button type="text" size="small" class="handle"
            >按住拖拽</el-button
          >
        </template>
      </el-table-column>
      <el-table-column width="60px" label="序号" type="index"></el-table-column>
      <!-- 此处如果只有行拖动,可以全部替换为 item -->
      <el-table-column
        v-for="(item, index) of dropCol"
        :key="`dropCol_${index}`"
        :prop="dropColumn[index].prop"
        :label="item.label"
        :width="item.width"
        :fixed="item.fixed"
      />

      <el-table-column label="操作" width="150">
        <template slot-scope="scope">
          <el-button size="small">{{ scope.row.edit }}</el-button>
          <el-button size="small">{{ scope.row.del }}</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script>
  import Sortable from "sortablejs";
  export default {
    name: "HelloWorld",
    props: {
      msg: String,
    },
    data() {
      return {
        tableData: [
          {
            roleId: 20001,
            roleName: "咯阿时候1",
            createTime: "2021-06",
            edit: "编辑",
            del: "删除",
          },
          {
            roleId: 20002,
            roleName: "咯阿时候2",
            createTime: "2021-07",
            edit: "编辑",
            del: "删除",
          },
          {
            roleId: 20003,
            roleName: "咯阿时候3",
            createTime: "2021-08",
            edit: "编辑",
            del: "删除",
          },
        ],
        dropColumn: [
          { prop: "roleId", label: "编码", width: 100 },
          { prop: "roleName", label: "角色名称" },
          { prop: "createTime", label: "创建时间" },
          { prop: "edit", label: "编辑", width: 180, fixed: "right" },
        ],
        dropCol: [
          { prop: "roleId", label: "编码", width: 100 },
          { prop: "roleName", label: "角色名称" },
          { prop: "createTime", label: "创建时间" },
          { prop: "edit", label: "编辑", width: 180, fixed: "right" },
        ],
      };
    },
    watch: {
      "tableOptions.data": {
        deep: true,
        handler: function (newData) {
          console.log(newData); // 可以发现每次拖拽后数据发生了改变
        },
      },
    },
    methods: {
      eventDrag() {
        this.rowDrop();
        this.columnDrop();
      },
      mounted() {},
      //行拖拽
      rowDrop() {
        //此处需要使用this.$refs.table.$el.querySelector,不然可能获取不到 tbody
        const tbody = this.$refs.table.$el.querySelector(
          ".el-table__body-wrapper tbody"
        );
        console.log(tbody);
        const _this = this;
        Sortable.create(tbody, {
          handle: ".handle", //此处指定拖拽元素
          animation: 150,
          onChoose() {
            //选择元素
            _this.dropColumn[_this.dropColumn.length - 1].fixed = false;
          },
          onUnchoose: function (evt) {
            // 取消选择元素
            _this.dropColumn[_this.dropColumn.length - 1].fixed = "right";
          },
          onEnd({ newIndex, oldIndex }) {
            // 拖拽完成
            const currRow = _this.tableData.splice(oldIndex, 1)[0];
            _this.tableData.splice(newIndex, 0, currRow);
          },
        });
      },
      //列拖拽
      columnDrop() {
        const wrapperTr = this.$refs.table.$el.querySelector(
          ".el-table__header-wrapper tr"
        );
        console.log(wrapperTr);
        this.sortable = Sortable.create(wrapperTr, {
          animation: 180,
          delay: 0,
          onEnd: (evt) => {
            const arr = JSON.parse(JSON.stringify(this.dropCol));
            const oldItem = arr[evt.oldIndex];
            arr.splice(evt.oldIndex, 1);
            arr.splice(evt.newIndex, 0, oldItem);
            this.$nextTick(() => {
              this.dropCol = arr;
            });
          },
        });
      },
    },
  };
</script>

4.在线链接

https://codesandbox.io/embed/gifted-hill-sdozr?fontsize=14&hidenavigation=1&theme=dark

文章引用:

https://www.cnblogs.com/enhengenhengNymph/p/14537289.html


文章作者:   leader755
版权声明:   本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 leader755 !
评论
 上一篇
抓包工具——charles 抓包工具——charles
1.Charles 设置 Proxy 代理和 Proxy SSL 代理1>设置 Proxy 代理(http 抓包) 2>设置 Proxy SSL 代理(https 抓包)Proxy -> SSL Proxying Set
2021-07-26
下一篇 
字体图标iconfont的使用 字体图标iconfont的使用
1.将从阿里矢量图标库中图标并下载到本地 2.使用图标(三种使用方式)1.使用 FontClass(最简单方式,支持字体样式定义但不支持多色字体)fontClass 支持字体的样式定义,但不支持多色字体,兼容性良好,当要替换图标时,只需要
2021-06-22
  目录