请教大佬们个问题,vue2中我有一个基础的el-table表格,表格里分置顶区域和非置顶区域,需求是置顶区域之间可以互相拖拽排序,非置顶区域可以互相拖拽排序,非置顶和置顶之间不可拖拽排序,
比如1.2.3条数据是置顶的,可以互相拖拽排序,4.5.6是非置顶数据,可以拖拽排序,但1.2.3和4.5.6之间不可互相拖拽,感谢各位大佬解惑
请教大佬们个问题,vue2中我有一个基础的el-table表格,表格里分置顶区域和非置顶区域,需求是置顶区域之间可以互相拖拽排序,非置顶区域可以互相拖拽排序,非置顶和置顶之间不可拖拽排序,
比如1.2.3条数据是置顶的,可以互相拖拽排序,4.5.6是非置顶数据,可以拖拽排序,但1.2.3和4.5.6之间不可互相拖拽,感谢各位大佬解惑
要实现您所描述的表格分组拖拽排序功能,您可以使用一些前端库,如 Sortable.js
或者 Vue.Draggable
(如果您在使用Vue.js)等,这些库提供了强大的拖拽排序功能。以下是一个基于 Sortable.js
的实现思路,因为它是一个轻量级的JavaScript库,适用于大多数场景。
首先,您需要在您的项目中引入Sortable.js。您可以通过CDN或npm来安装。
<!-- 通过CDN引入Sortable.js -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/dist/sortable.min.js"></script>
假设您的表格HTML结构如下:
<table id="myTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Is Sticky</th>
</tr>
</thead>
<tbody>
<tr data-group="sticky">
<td>1</td>
<td>Item 1</td>
<td>Yes</td>
</tr>
<tr data-group="sticky">
<td>2</td>
<td>Item 2</td>
<td>Yes</td>
</tr>
<tr data-group="non-sticky">
<td>3</td>
<td>Item 3</td>
<td>No</td>
</tr>
<!-- 更多行... -->
</tbody>
</table>
注意,这里使用 data-group
属性来区分置顶和非置顶的行。
接下来,使用Sortable.js初始化拖拽排序,但需要分别处理置顶和非置顶的行。
// 初始化置顶区域的拖拽排序
var stickyList = document.querySelectorAll('tr[data-group="sticky"]');
Sortable.create(stickyList, {
group: "sticky",
animation: 150,
onEnd: function (/**Event*/evt) {
// 拖拽结束后的回调,可以用来更新数据等
console.log('Sticky item moved!');
}
});
// 初始化非置顶区域的拖拽排序
var nonStickyList = document.querySelectorAll('tr[data-group="non-sticky"]');
Sortable.create(nonStickyList, {
group: "non-sticky",
animation: 150,
onEnd: function (/**Event*/evt) {
// 拖拽结束后的回调
console.log('Non-sticky item moved!');
}
});
// 注意:由于Sortable.js默认不支持跨列表拖拽,上面的分组设置确保了置顶和非置顶区域之间不能互相拖拽
然而,这里有个小问题:Sortable.js通常用于列表(如<ul>
或<ol>
),而不是表格行(<tr>
)。对于表格,您可能需要考虑使用其他库(如Vue.Draggable
在Vue中,或实现自定义的拖拽逻辑),或者将表格行转换为可拖拽的列表项,并在拖动后更新表格的DOM。
如果您想要继续使用表格形式并希望保持结构不变,可能需要寻找或编写一个更适用于表格的拖拽库,或者采用一些DOM操作技巧来模拟拖拽效果。
如果Sortable.js不完全符合您的需求,您还可以考虑使用像jQuery UI
的Sortable插件(虽然它也不再是官方维护的重点),或者完全自定义拖拽逻辑,使用HTML5的拖放API (drag
和 drop
事件) 来实现。
npm install sortablejs
<template>
<div>
<!-- 置顶区域 -->
<el-table :data="topData" row-class-name="top-row" ref="topTable">
<el-table-column prop="id" label="ID"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
<!-- 非置顶区域 -->
<el-table :data="normalData" row-class-name="normal-row" ref="normalTable">
<el-table-column prop="id" label="ID"></el-table-column>
<el-table-column prop="name" label="名称"></el-table-column>
</el-table>
</div>
</template>
<script>
import Sortable from 'sortablejs';
export default {
data() {
return {
topData: [
{ id: 1, name: '置顶项1' },
{ id: 2, name: '置顶项2' },
{ id: 3, name: '置顶项3' },
],
normalData: [
{ id: 4, name: '普通项1' },
{ id: 5, name: '普通项2' },
{ id: 6, name: '普通项3' },
],
};
},
mounted() {
this.initSortable();
},
methods: {
initSortable() {
// 置顶区域拖拽
const topTable = this.$refs.topTable.$el.querySelector('.el-table__body tbody');
Sortable.create(topTable, {
group: 'top-group', // 置顶组标识
animation: 150,
onEnd: ({ oldIndex, newIndex }) => {
const movedItem = this.topData.splice(oldIndex, 1)[0];
this.topData.splice(newIndex, 0, movedItem);
},
});
// 非置顶区域拖拽
const normalTable = this.$refs.normalTable.$el.querySelector('.el-table__body tbody');
Sortable.create(normalTable, {
group: 'normal-group', // 非置顶组标识
animation: 150,
onEnd: ({ oldIndex, newIndex }) => {
const movedItem = this.normalData.splice(oldIndex, 1)[0];
this.normalData.splice(newIndex, 0, movedItem);
},
});
},
},
};
</script>
<style>
.top-row {
background-color: #f5f7fa; /* 置顶区域样式 */
}
.normal-row {
background-color: #ffffff; /* 非置顶区域样式 */
}
</style>
10 回答11.2k 阅读
5 回答4.8k 阅读✓ 已解决
4 回答3.1k 阅读✓ 已解决
2 回答2.8k 阅读✓ 已解决
2 回答4.8k 阅读✓ 已解决
4 回答4.4k 阅读✓ 已解决
4 回答1.9k 阅读✓ 已解决
拖拽的时候:当前位置 -> 目标位置