el-table表格拖拽到el-tree树 使用html5的draggable属性

258 阅读1分钟
<template>
  <div class="app-container">
    <!-- el-table表格拖拽到el-tree树 -->
    <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
          >
            <!--  data-id用于dataset获取拖拽到的节点id  -->
            <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++) {
              // 开启tree树拖拽
              // treeNodes[index2].draggable = false
              treeNodes[index2].ondragstart = (e) => {
                console.log('触发ondragstart', e)
              }
              treeNodes[index2].ondragover = (e) => {
                // console.log('触发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) => {
            // console.log('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>