1、此功能已集成到[TTable组件中]—Vue2TTable组件 、Vue3TTable组件
2、最终效果
3、安装sortablejs
npm install sortablejs --save
4、Vue2实现方式
<template>
<el-table
ref="el-table"
:data="tableData"
:class="{'cursor':isCopy,'row_sort':isRowSort,'highlightCurrentRow':highlightCurrentRow,'radioStyle':(table.firstColumn&&table.firstColumn.type==='radio'),'treeProps':isShowTreeStyle}"
v-bind="$attrs"
v-on="$listeners"
:highlight-current-row="highlightCurrentRow"
:border="table.border||isTableBorder"
:span-method="spanMethod||objectSpanMethod"
:cell-class-name="cellClassNameFuc"
@sort-change="soltHandle"
@row-click="rowClick"
@cell-dblclick="cellDblclick"
>
....
</el-table>
</template>
<script>
import Sortable from 'sortablejs'
props: {
// table所需数据
table: {
type: Object,
default: () => {
return {}
}
},
// 是否开启行拖拽
isRowSort: {
type: Boolean,
default: false
}
...
},
data() {
return {
tableData: this.table?.data
}
},
watch: {
'table.data': {
handler(val) {
this.tableData = val
},
deep: true // 深度监听
}
},
mounted() {
this.initSort()
},
methods: {
// 行拖拽
initSort() {
if (!this.isRowSort) return
const el = this.$refs['el-table'].$el.querySelector('.el-table__body-wrapper > table > tbody')
new Sortable(el, {
animation: 150, // 动画
onEnd: evt => {
const curRow = this.tableData.splice(evt.oldIndex, 1)[0]
this.tableData.splice(evt.newIndex, 0, curRow)
this.$emit('rowSort', this.tableData)
}
})
}
}
</script>
5、Vue3实现方式
<template>
<div class="t-table" ref="TTableBox">
....
<el-table
ref="TTable"
:data="state.tableData"
:class="{
cursor: isCopy,
row_sort: isRowSort,
highlightCurrentRow: highlightCurrentRow,
radioStyle: table.firstColumn && table.firstColumn.type === 'radio',
}"
v-bind="$attrs"
size="default"
:highlight-current-row="highlightCurrentRow"
:border="table.border || isTableBorder"
@cell-dblclick="cellDblclick"
@row-click="rowClick"
:cell-class-name="cellClassNameFuc"
>
....
</el-table>
</div>
</template>
<script setup lang="ts">
import { computed, ref, watch, useSlots, reactive, onMounted } from 'vue'
import Sortable from 'sortablejs'
const props = defineProps({
// table所需数据
table: {
type: Object,
default: () => {
return {}
},
required: true,
},
// 表头数据
columns: {
type: Array,
default: () => {
return []
},
// required: true
},
// 是否开启行拖拽
isRowSort: {
type: Boolean,
default: false,
}
...
})
// 初始化数据
const state = reactive({
tableData: props.table.data,
...
})
// 获取el-table ref
const TTable: any = ref<HTMLElement | null>(null)
// 获取t-table ref
const TTableBox: any = ref<HTMLElement | null>(null)
// 抛出事件
const emits = defineEmits([
'rowSort',
....
])
watch(
() => props.table.data,
(val) => {
// console.log(111, val)
state.tableData = val
},
{ deep: true }
)
onMounted(() => {
initSort()
})
// 行拖拽
const initSort = () => {
if (!props.isRowSort) return
const el = TTableBox.value.querySelector('.el-table__body-wrapper tbody')
// console.log('3333', el)
Sortable.create(el, {
animation: 150, // 动画
onEnd: (evt) => {
const curRow = state.tableData.splice(evt.oldIndex, 1)[0]
state.tableData.splice(evt.newIndex, 0, curRow)
emits('rowSort', state.tableData)
},
})
}
</script>
注意事项,el-table需要配置row-key
且保持唯一性,不然会出现排序不对的情况
6、sortablejs其他options配置
7、组件地址
Vue3组件地址
Vue2组件地址
8、相关文章
Vue2基于ElementUi再次封装基础组件文档
vue3+ts基于Element-plus再次封装基础组件文档