el-table拖拽之sortablejs

el-table拖拽之sortablejs

有需求要求在element-ui 中的表格 el-table 中支持拖拽,el-table 本身不支持拖拽,所以要引入三方插件 sortablejs 来支持,这个插件的基本思路就是在拖拽后返回被拖拽的新老角标给onEnd回调函数,然后前端在根据返回的角标将原数据进行重新组合

1.安装:npm install sortablejs --save

2.引入

import Sortable from "sortablejs"

3.创建拖拽实例(这段代码执行应在数据渲染结束后,否则无法获取对应行)

el-table务必指定row-key,row-key必须是唯一的,如ID,不然会出现排序不对的情况

html片段

<template>
  <div class="table">
    <el-table
      ref="dragTable"
      :data="tableData"
      row-key="id"
      border
      :row-class-name="tableRowClassName"
    >
      <el-table-column prop="date" label="日期"></el-table-column>
      <el-table-column prop="name" label="姓名"></el-table-column>
      <el-table-column prop="address" label="地址"></el-table-column>
      <el-table-column label="操作">
        <template>
          <el-button class="move" type="text" size="small">拖 拽</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

javascript片段

// 获取表格row的父节点
const ele = this.$refs.dragTable.$el.querySelector(
  ".el-table__body > tbody"
);

Sortable.create(ele, {
	animation: 150, //动画
	handle: ".move", //指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽)
	// 结束拖动事件
	onEnd: ({ newIndex, oldIndex }) => {
	  console.log(
	    "结束拖动",
	    `拖动前索引${oldIndex}---拖动后索引${newIndex}`
	 );
	 // 将拖动后的新顺序重新组合
	 const currRow = _this.tableData.splice(oldIndex, 1)[0];
	 this.tableData.splice(newIndex, 0, currRow);
	},
});

如果上面的配置好了刷新就能生效了,上面的代码已经完全能满足基本的拖拽需求

4.全部代码(下面代码不一定全能用上,要根据业务需求按需配置,避免冗余代码和意想不到的bug)

<template>
  <div class="table">
    <el-table
      ref="dragTable"
      :data="tableData"
      row-key="id"
      border
      :row-class-name="tableRowClassName"
    >
      <el-table-column prop="date" label="日期"></el-table-column>
      <el-table-column prop="name" label="姓名"></el-table-column>
      <el-table-column prop="address" label="地址"></el-table-column>
      <el-table-column label="操作">
        <template>
          <el-button class="move" type="text" size="small">拖 拽</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
import Sortable from "sortablejs";
export default {
  data() {
    return {
      tableData: [
        {
          id: "1",
          name: "text_1",
          date: "1111-11-11",
          address: "测试_1",
        },
        {
          id: "2",
          name: "text_2_不可拖拽",
          date: "2222-22-22",
          address: "测试_2_不可拖拽",
          disabled: true,
        },
        {
          id: "3",
          name: "text_3",
          date: "3333-33-33",
          address: "测试_3",
        },
        {
          id: "4",
          name: "text_4",
          date: "4444-44-44",
          address: "测试_4",
        },
        {
          id: "5",
          name: "text_5",
          date: "5555-55-55",
          address: "测试_5",
        },
      ],
    };
  },
  methods: {
    // 创建sortable实例
    initSortable() {
      // 获取表格row的父节点
      const ele = this.$refs.dragTable.$el.querySelector(
        ".el-table__body > tbody"
      );
      // 创建拖拽实例
      let dragTable = Sortable.create(ele, {
        animation: 150, //动画
        disabled: false, // 拖拽不可用? false 启用(刚刚渲染表格的时候起作用,后面不起作用)
        handle: ".move", //指定拖拽目标,点击此目标才可拖拽元素(此例中设置操作按钮拖拽)
        filter: ".disabled", //指定不可拖动的类名(el-table中可通过row-class-name设置行的class)
        dragClass: "dragClass", //设置拖拽样式类名
        ghostClass: "ghostClass", //设置拖拽停靠样式类名
        chosenClass: "chosenClass", //设置选中样式类名
        // 开始拖动事件
        onStart: () => {
          console.log("开始拖动");
        },
        // 结束拖动事件
        onEnd: ({ newIndex, oldIndex }) => {
          console.log(
            "结束拖动",
            `拖动前索引${oldIndex}---拖动后索引${newIndex}`
          );
            const currRow = _this.tableData.splice(oldIndex, 1)[0];
          this.tableData.splice(newIndex, 0, currRow);
        },
      });
    },
    // 设置表格row的class
    tableRowClassName({ row }) {
      if (row.disabled) {
        return "disabled";
      }
      return "";
    },
  },
  mounted() {
    this.initSortable();
  },
};
</script>
//注意如果加上scoped 样式就可能不起作用
<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>

5.下面还有一个例子能实现列拖拽

在这里插入图片描述

借鉴网上的说法下载依赖有两种方式,这个我也贴出来以便自己日后使用
1.引入sortable.js的包: npm install sortable.js --save
2.或者npm i -S vuedraggable
vuedraggable依赖 Sortable.js,所以下载了vuedraggable,我们便可以直接引入Sortable使用Sortable的特性。
vuedraggable是Sortable一种加强,实现组件化的思想,可以结合Vue,使用起来更方便

<template>
  <div style="width:800px">

    <el-table :data="tableData"
      border
      row-key="id"
      align="left">
     <el-table-column v-for="(item, index) in col"
        :key="`col_${index}`"
        :prop="dropCol[index].prop"
        :label="item.label"> 
      </el-table-column>
    </el-table>
    <pre style="text-align: left">
      {{dropCol}}
    </pre>
    <hr>
    <pre style="text-align: left">
      {{tableData}}
    </pre>
  </div>
</template>
<script>
import Sortable from 'sortablejs'
export default {
  data() {
    return {
      col: [
        {
          label: '日期',
          prop: 'date'
        },
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'address'
        }
      ],
      dropCol: [
        {
          label: '日期',
          prop: 'date'
        },
        {
          label: '姓名',
          prop: 'name'
        },
        {
          label: '地址',
          prop: 'address'
        }
      ],
      tableData: [
        {
          id: '1',
          date: '2016-05-02',
          name: '王小虎1',
          address: '上海市普陀区金沙江路 100 弄'
        },
        {
          id: '2',
          date: '2016-05-04',
          name: '王小虎2',
          address: '上海市普陀区金沙江路 200 弄'
        },
        {
          id: '3',
          date: '2016-05-01',
          name: '王小虎3',
          address: '上海市普陀区金沙江路 300 弄'
        },
        {
          id: '4',
          date: '2016-05-03',
          name: '王小虎4',
          address: '上海市普陀区金沙江路 400 弄'
        }
      ]
    }
  },
  mounted() {
    this.rowDrop()
    this.columnDrop()
  },
  methods: {
    //行拖拽
    rowDrop() {
      const tbody = document.querySelector('.el-table__body-wrapper tbody')
      const _this = this
      Sortable.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          const currRow = _this.tableData.splice(oldIndex, 1)[0]
          _this.tableData.splice(newIndex, 0, currRow)
        }
      })
    },
    //列拖拽
    columnDrop() {
      const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        onEnd: evt => {
          const oldItem = this.dropCol[evt.oldIndex]
          this.dropCol.splice(evt.oldIndex, 1)
          this.dropCol.splice(evt.newIndex, 0, oldItem)
        }
      })
    }
  }
}
</script>
  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要取消在 el-table拖拽 input 的功能,可以通过在 el-table-column 中设置 `sortable` 属性为 false,例如: ```html <el-table :data="tableData"> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age" :sortable="false"></el-table-column> <el-table-column prop="gender" label="Gender"></el-table-column> </el-table> ``` 这样就可以禁用对 `age` 列的拖拽排序功能。 如果要使用 sortablejs 进行拖拽排序,但不希望 input 元素被拖拽,可以通过在 el-table-column 中设置 `sortable-handler` 属性为一个选择器字符串,表示只有选中的元素才能触发拖拽事件,例如: ```html <el-table :data="tableData"> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age" :sortable="true" sortable-handler=".drag-handle"></el-table-column> <el-table-column prop="gender" label="Gender"></el-table-column> </el-table> ``` 然后在 el-table-column 中的表头 slot 中添加一个拖拽手柄元素,例如: ```html <el-table :data="tableData"> <el-table-column prop="name" label="Name"></el-table-column> <el-table-column prop="age" label="Age" :sortable="true" sortable-handler=".drag-handle"> <template slot="header"> <div class="drag-handle">Drag</div> </template> </el-table-column> <el-table-column prop="gender" label="Gender"></el-table-column> </el-table> ``` 这样就只有拖拽手柄元素才能触发拖拽事件,而 input 元素不会被拖拽

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值