行百里者半九十
关于拖拽效果,之前手动写过拖拽交换的逻辑,但因为这次拖拽的是element的table行,所以想找下有没有好用的插件。
经过一番查找,找到一个很nice的插件SortableJS
,功能强大的JavaScript 拖拽库
使用介绍:
- 安装插件并引入
- 获取拖拽元素的父元素
- 创建并配置相关参数
- 回调函数使用
注意:
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】