element table实现拖拽效果

2023-02-23 21:18:21

行百里者半九十

关于拖拽效果,之前手动写过拖拽交换的逻辑,但因为这次拖拽的是element的table行,所以想找下有没有好用的插件。
经过一番查找,找到一个很nice的插件SortableJS功能强大的JavaScript 拖拽库

使用介绍:

  1. 安装插件并引入
  2. 获取拖拽元素的父元素
  3. 创建并配置相关参数
  4. 回调函数使用

注意:
element table务必指定row-key,row-key必须是唯一的,如ID,不然会出现排序不对的情况,但是不可用index


效果图:
在这里插入图片描述

在这里插入图片描述


需求:
1.仅有按住排序列里的按钮,才可进行拖拽排序
2.拖拽过成中不进行排序,仅当松开拖拽后进行交换
3.拖拽目标交换行,高亮提示


一、安装插件并引入

yarn add sortablejs --save

import Sortable from "sortablejs";

二、插件使用

实例讲解:

html:

<template>
  <div>
    <el-table :data="tableData" row-key="id" :row-class-name="tableRowClassName">
      <el-table-column
        v-for="(item, index) in col"
        :key="`col_${index}`"
        :prop="item.prop"
        :label="item.label"
        :width="item.prop == 'sort'?'100px':''"
      >
      <!-- 自定义渲染模版 -->
        <template slot-scope="scope">
          <!-- 当列key为 sort 时,渲染一个手柄icon -->
          <template v-if="item.prop =='sort'">
            <div class="handle_move">
              <i :class="scope.row['sort']" />
            </div>
          </template>
          <template v-else>
            <span style="margin-left: 10px">{{scope.row[`${item.prop}`]}}</span>
          </template>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

js:

data(){
	return {
		tableData:[
		  {
		    id: "1",
		    date: "2016-05-02",
		    name: "王小虎1",
		    address: "上海市普陀区金沙江路 100 弄",
		    sort: "el-icon-d-caret"
		  },
		  {
		    id: "2",
		    date: "2016-05-04",
		    name: "王小虎2",
		    address: "上海市普陀区金沙江路 200 弄",
		    sort: "el-icon-d-caret"
		  },
		  {
		    id: "3",
		    date: "2016-05-01",
		    name: "王小虎3",
		    address: "上海市普陀区金沙江路 300 弄",
		    sort: "el-icon-d-caret"
		  },
		  {
		    id: "4",
		    date: "2016-05-03",
		    name: "王小虎4",
		    address: "上海市普陀区金沙江路 400 弄",
		    sort: "el-icon-d-caret"
		  }
		],
		oldIndex: null,
        newIndex: null,
        col: [
          { label: "日期", prop: "date" },
          { label: "姓名", prop: "name" },
          { label: "地址", prop: "address" },
          { label: "排序", prop: "sort" }
        ],
	}
},
mounted(){
	// 页面挂载完成,开始创建拖拽
	this.init()
},
methods:{
	init(){
		// 1. 获取拖拽元素的父元素
		// 因为使用的element的table 所以可直接获取tbody
		let el =  document.querySelector(".el-table__body-wrapper tbody");
		
		
		// 2. 创建并配置相关参数
		var sortable = new Sortable(el, {
			// 此处进行配置 及 回调函数的使用
			
			// 因为我的需求是只有按住手柄才能进行拖拽,故而设置此参数
			handle:'.handle_move', // css选择器的字符串 若设置该值,则表示只有按住拖动手柄才能使列表单元进行拖动
			
			// 我的需求是行拖拽,所以该值设置为行class
			draggable:'.el-table__row', // 允许拖拽的项目类名
		
			const _this = this;	
			
			// 因为拖拽过程中不尽兴位置调整,所以就要记录拖拽行初始位置以及目标位置
			// 拖拽中 回调函数
			 onMove(customEvent) {
	          // 禁止在拖拽过程中交换位置
	          // 可将初始位置及目标位置进行记录
	          _this.oldIndex = customEvent.dragged.rowIndex; //  初始位置
	          _this.newIndex = customEvent.related.rowIndex; // 目标位置
	          return false;  // 不进行交换
	          // 返回值有三个
	          // return false; — for cancel
	          // return -1; — insert before target
	          // return 1; — insert after target
	        },
			
			// 拖拽结束,调整位置
			onEnd() {
	          // 在拖拽结束后,获取初始及目标位置
	          const { newIndex, oldIndex } = _this;
	          const currRow = _this.tableData.splice(oldIndex, 1)[0];
	          _this.tableData.splice(newIndex, 0, currRow);
	          // 此时记得把交换后的数据,发送给后端进行记录
	          // this.$axios({url,method,data}).......
	          
	          // 拖拽完成,初始位置及目标位置重置
	          _this.newIndex = null;
	          _this.oldIndex = null;
	        },
		})

	},
	// 目标位置高亮
	// 给目标行 添加高亮样式
	 tableRowClassName({ row, rowIndex }) {
      if (rowIndex === this.newIndex) {
        return "warning-row";
      }
      return "";
    }
}

css:

.handle_move {
  cursor: move;
}
.el-table .warning-row {
  background: oldlace;
}

至此,即可实现 拖拽进行数据位置交换。
当然,如果有差异之处,可自行修改调整。但是产品需求要有不合理之处,可以和产品进行沟通协商哦~


更多api可自行查找:
SortableJS官网地址:【sortable】
Sortable options地址:【sortable options】

  • 作者:Dark_programmer
  • 原文链接:https://blog.csdn.net/Dark_programmer/article/details/119176036
    更新时间:2023-02-23 21:18:21