如需有对el-table表格进行拖拽的需求,请点击:
eleplus对el-table表格进行拖拽(使用sortablejs进行列拖拽和行拖拽):-CSDN博客
如果你已实现拖拽需求,但拖拽后发现表头并未改变的话,请点击:
解决el-table表格拖拽后,只改变了数据,表头没变的问题-CSDN博客
先看看是不是你想要的。
限制拖拽
Sortable.js中文网
sortableJs有个配置项是filter,过滤掉不可进行拖拽的列或行。
本文采用vue3+ele-plus的table组件结合sortableJs插件对表格拖拽需求进行开发:
列拖拽:
使用 :header-cell-class-name="headerCellClassName"对el-table的列增加headerClassFilter类名,有此类名的行不可进行拖拽(在Sortable.create实例中对headerClassFilter类名进行过滤,即filter绑定的类名)。
javascript
<template>
<div>
<el-table
:data="tableData"
border
scrollbar-always-on
ref="tableHeader"
row-key="id"
:header-cell-class-name="headerCellClassName"
>
<template v-for="item in setColumns" :key="item.label">
<!-- 操作列 -->
<el-table-column
v-if="item.prop === 'oprate'"
fixed="right"
:prop="item.prop"
:label="item.label"
>
<template #header>
<div class="search-title">
<div :class="checked ? 'search-titleName' : ''">操作</div>
<el-icon class="search-icon" @click="search">
<Search color="#409EFF" />
</el-icon>
</div>
</template>
</el-table-column>
<!-- 序号列 -->
<el-table-column
v-else-if="item.prop === 'index'"
:type="item.type"
:label="item.label"
:width="item.width || 100"
/>
<!-- 数据列 -->
<el-table-column
v-else
:prop="item.prop"
:label="item.label"
:width="item.width || 100"
/>
</template>
</el-table>
</div>
</template>
<script setup lang='js'>
import { ref, onMounted } from 'vue'
import Sortable from 'sortablejs';
let setColumns = ref([
{
prop: 'index',
label: '序号',
type: 'index'
},
{
prop: 'name',
label: '姓名'
},
{
prop: 'address',
label: '地址'
},
{
prop: '11',
label: '1'
},
{
prop: '22',
label: '2'
},
{
prop: '33',
label: '3'
},
{
prop: '44',
label: '4'
},
{
prop: '55',
label: '5'
},
{
prop: '66',
label: '6'
},
{
prop: 'oprate',
lable: ''
}
])
let tableData = ref([
{
name: 'Tom1',
address: '上海',
11: 11,
22: 21,
33: 31,
44: 41,
55: 51,
66: 61,
id: 1
},
{
name: 'Tom2',
address: '北京',
11: 12,
22: 22,
33: 32,
44: 42,
55: 52,
66: 62,
id: 2
},
{
name: 'Tom3',
address: '广州',
11: 13,
22: 23,
33: 33,
44: 43,
55: 53,
66: 63,
id: 3
},
{
name: 'Tom4',
address: '深圳',
11: 14,
22: 24,
33: 34,
44: 44,
55: 54,
66: 64,
id: 4
}
])
let sortable;
const tableHeader = ref(null);
onMounted(() => {
columnDrag(); // 初始化列拖拽事件
})
const headerCellClassName = ({column}) => { // 给序号和操作列增加类名,意在这两列不可进行拖拽
if (column.label === '序号' || column.property === 'oprate') {
return 'headerClassFilter'
}
}
const columnDrag = () => {
let el = tableHeader.value.$el.querySelector('.el-table__header-wrapper tr')
Sortable.create(el, {
animation: 180,
delay: 0,
filter: '.headerClassFilter', // 类名为headerClassFilter的列不可进行拖拽
onMove({ related }) { // 移动单元格时,如果related.className包含headerClassFilter,即不可拖拽
return related.className.indexOf('headerClassFilter') === -1;
},
onEnd(evt) {
const oldItem = setColumns.value[evt.oldIndex]
setColumns.value.splice(evt.oldIndex, 1);
setColumns.value.splice(evt.newIndex, 0, oldItem);
}
})
}
</script>
<style scoped>
.search-title{
display: flex;
/* justify-content: space-around; */
}
.search-titleName{
color: #409EFF;
}
.search-icon{
cursor: pointer;
margin-top: 5px;
margin-left: 10px;
}
:deep(.headerClassFilter){
background-color: red !important;
cursor: not-allowed;
}
:deep(.el-table .rowClassFilter){
background-color: #ffeebc !important;
cursor: not-allowed;
}
</style>
行拖拽:
使用 :row-class-name="rowClassName"对el-table的行增加rowClassFilter类名,有此类名的行不可进行拖拽(在Sortable.create实例中对rowClassFilter类名进行过滤,即filter绑定的类名)。
javascript
<template>
<div>
<el-table
:data="tableData"
border
scrollbar-always-on
ref="tableHeader"
row-key="id"
:row-class-name="rowClassName"
>
<template v-for="item in setColumns" :key="item.label">
<!-- 操作列 -->
<el-table-column
v-if="item.prop === 'oprate'"
fixed="right"
:prop="item.prop"
:label="item.label"
>
<template #header>
<div class="search-title">
<div :class="checked ? 'search-titleName' : ''">操作</div>
<el-icon class="search-icon" @click="search">
<Search color="#409EFF" />
</el-icon>
</div>
</template>
</el-table-column>
<!-- 序号列 -->
<el-table-column
v-else-if="item.prop === 'index'"
:type="item.type"
:label="item.label"
:width="item.width || 100"
/>
<!-- 数据列 -->
<el-table-column
v-else
:prop="item.prop"
:label="item.label"
:width="item.width || 100"
/>
</template>
</el-table>
</div>
</template>
<script setup lang='js'>
import { ref, watch, onMounted } from 'vue'
import Sortable from 'sortablejs';
let setColumns = ref([
{
prop: 'index',
label: '序号',
type: 'index'
},
{
prop: 'name',
label: '姓名'
},
{
prop: 'address',
label: '地址'
},
{
prop: '11',
label: '1'
},
{
prop: '22',
label: '2'
},
{
prop: '33',
label: '3'
},
{
prop: '44',
label: '4'
},
{
prop: '55',
label: '5'
},
{
prop: '66',
label: '6'
},
{
prop: 'oprate',
lable: ''
}
])
let tableData = ref([
{
name: 'Tom1',
address: '上海',
11: 11,
22: 21,
33: 31,
44: 41,
55: 51,
66: 61,
id: 1
},
{
name: 'Tom2',
address: '北京',
11: 12,
22: 22,
33: 32,
44: 42,
55: 52,
66: 62,
id: 2
},
{
name: 'Tom3',
address: '广州',
11: 13,
22: 23,
33: 33,
44: 43,
55: 53,
66: 63,
id: 3
},
{
name: 'Tom4',
address: '深圳',
11: 14,
22: 24,
33: 34,
44: 44,
55: 54,
66: 64,
id: 4
}
])
let sortable;
const tableHeader = ref(null);
onMounted(() => {
rowDrag() // 初始化行拖拽事件
})
const rowClassName = (data) => {
if (data.rowIndex === 0 || data.rowIndex === tableData.value.length - 1) {
return 'rowClassFilter'
}
}
const rowDrag = () => {
let el = tableHeader.value.$el.querySelector('.el-table__body-wrapper tbody')
Sortable.create(el, {
animation: 180,
delay: 0,
filter: '.rowClassFilter', // 类名为rowClassFilter的行不可进行拖拽
onMove({related}) {
return related.className.indexOf('rowClassFilter') === -1;
},
onEnd(evt) {
const oldItem = tableData.value[evt.oldIndex]
tableData.value.splice(evt.oldIndex, 1);
tableData.value.splice(evt.newIndex, 0, oldItem);
}
})
}
</script>
<style scoped>
.search-title{
display: flex;
/* justify-content: space-around; */
}
.search-titleName{
color: #409EFF;
}
.search-icon{
cursor: pointer;
margin-top: 5px;
margin-left: 10px;
}
:deep(.headerClassFilter){
background-color: red !important;
cursor: not-allowed;
}
:deep(.el-table .rowClassFilter){
background-color: #ffeebc !important;
cursor: not-allowed;
}
</style>