<template>
<div class="app-container">
<div class="main-wrap">
<el-button @click="rollback" size="mini" type="primary">回滚</el-button>
<div class="flex-box">
<div class="tree-dragTable">
<el-tree
ref="tree"
:data="treeList"
node-key="id"
:props="{
children: 'children',
label: 'label'
}"
default-expand-all
>
<span class="custom-tree-node" :class="{'active': selectTreeId === data.id && isDragTable}"
:data-id="data.id" slot-scope="{ node, data }"
>
<span class="label">
{{ node.label }}
</span>
</span>
</el-tree>
</div>
<el-table
border
height="600px"
row-key="id"
id="dragTable"
:data="dataList"
>
<el-table-column label="用户编号" align="center" prop="id"/>
<el-table-column label="用户名称" align="center" prop="username"/>
<el-table-column label="用户账号" align="center" prop="account"/>
</el-table>
</div>
</div>
</div>
</template>
<script>
import { copyObj } from '@/biz/utils/common'
export default {
data() {
return {
isDragTable: false,
selectTreeId: undefined,
historyData: {},
historyIndex: undefined,
dataList: [
{
id: '1001',
username: 'admin',
account: 'admin'
},
{
id: '1002',
username: '张三',
account: 'zs'
},
{
id: '1003',
username: '李四',
account: 'ls'
}
],
treeList: [
{
label: '一级 1',
id: '1',
children: [{
label: '二级 1-1',
id: '11',
children: [{
id: '111',
label: '三级 1-1-1'
}]
}]
}, {
label: '一级 2',
id: '2',
children: [{
id: '21',
label: '二级 2-1',
children: [{
id: '211',
label: '三级 2-1-1'
}]
}, {
label: '二级 2-2',
id: '22',
children: [{
id: '221',
label: '三级 2-2-1'
}]
}]
}, {
label: '一级 3',
id: '3',
children: [{
id: '31',
label: '二级 3-1',
children: [{
id: '311',
label: '三级 3-1-1'
}]
}, {
id: '32',
label: '二级 3-2',
children: [{
id: '321',
label: '三级 3-2-1'
}]
}]
}]
}
},
created() {
this.getList()
},
methods: {
getList() {
this.$nextTick(() => {
this.openTableDrop();
});
},
openTableDrop() {
const tbody = document.querySelector('#dragTable tbody')
if (tbody) {
const dataList = this.dataList
const tr = tbody.getElementsByTagName('tr')
for (let index = 0; index < tr.length; index++) {
tr[index].draggable = true
tr[index].ondragstart = () => {
console.log(index)
const treeNodes = document.getElementsByClassName('tree-dragTable')[0].getElementsByClassName('el-tree-node__content')
for (let index2 = 0; index2 < treeNodes.length; index2++) {
treeNodes[index2].ondragstart = (e) => {
console.log('触发ondragstart', e)
}
treeNodes[index2].ondragover = (e) => {
this.isDragTable = true
this.selectTreeId = treeNodes[index2].getElementsByClassName('custom-tree-node')[0].dataset.id
e.preventDefault()
}
treeNodes[index2].ondrop = () => {
this.selectTreeId = undefined
console.log('拖动的表格数据是:', dataList[index])
copyObj(dataList[index], this.historyData)
const treeId = treeNodes[index2].getElementsByClassName('custom-tree-node')[0].dataset.id
this.setData(treeId, this.treeList, dataList[index])
console.log('拖动到的树ID是:' + treeId)
this.dataList.splice(index, 1)
console.log(this.dataList)
console.log(this.historyData)
this.historyIndex = index
}
}
}
tr[index].ondragover = (e) => {
e.preventDefault()
}
tr[index].ondrop = (e) => {
console.log('ondrop', e)
}
tr[index].ondragend = (e) => {
this.isDragTable = false
console.log('ondragend', e)
}
}
}
},
rollback() {
console.log(this.dataList, this.historyIndex)
if (!this.historyData?.id) return
if (!this.dataList?.length) {
this.historyIndex = 0
}
this.dataList.splice(this.historyIndex, 0, this.historyData)
this.rollbackData(this.treeList)
this.$nextTick(() => {
this.historyIndex = undefined
this.historyData = {}
this.openTableDrop()
})
},
rollbackData(data) {
data.forEach((item, index) => {
if (item.id === this.historyData.id) {
data.splice(index, 1)
}
if (item.children?.length) {
this.rollbackData(item.children)
}
})
},
setData(id, treeList, obj) {
treeList.forEach(item => {
if (item.id === id) {
if (!item.children?.length) {
this.$set(item, 'children', [])
}
item.children.push({
label: obj?.username,
id: obj?.id,
data: obj
})
}
if (item.children?.length) {
this.setData(id, item.children, obj)
}
})
},
}
}
</script>
<style lang="scss" scoped>
.flex-box {
display: flex;
.tree-dragTable {
background: #fff;
width: 200px;
border: 1px solid #333;
height: 600px;
}
}
.active {
color: red;
}
</style>