vue + element 实现可拖动表格,element tree层级线样式

本文展示了如何使用Vue.js和Element UI的el-tree组件创建一个可拖动的表格,通过允许拖放操作实现节点的重新排序。在拖放过程中,`allowDrop`方法用于控制拖放行为,确保只有特定类型的节点可以被拖放。同时,代码中预定义了模拟数据,并设置了表头。虽然目前拖放操作未直接触发接口请求,但可以通过扩展此功能实现实时更新后台数据。
摘要由CSDN通过智能技术生成

新建一个vue文件copy进去就可以看到效果,想要实现拖动的时候 请求接口 或者判断能否拖动等,请参考element tree组件

<template>
  <div id='draggableTable'>

    <!-- 表头 -->
    <div class="drat-header">

      <div class="drat-item-header"
        :class='{"drat-name-header": item.label == "名称"}'
        :style='{"float": item.label != "名称" ? "right" : ""}'
        v-for='item in headerList' :key='item.id'>
        {{item.label}}
      </div>
    </div>

    <el-tree
      :data="tableData"
      node-key="id"
      default-expand-all
      icon-class='el-icon-arrow-right'
      :allow-drop='allowDrop'
      draggable>

      <div class='drat-body' slot-scope="{ node, data }">

        <div class="drat-name drat-val-body">
          {{data.name}}
        </div>

        <div class="drat-val-right">
          <div class="drat-val-body" style='float: left;'>
            {{data.code}}
          </div>

          <div class="drat-val-body" style='float: left;'>
            {{data.time}}
          </div>

          <div class="drat-val-body" style='float: left;'>
            {{data.status}}
          </div>

          <div class="drat-val-body" style='float: left;'>
            {{data.operation}}
          </div>
        </div>

      </div>

    </el-tree>

  </div>
</template>

<script>
export default {
  name: 'draggableTable',

  methods: {

    allowDrop (draggingNode, dropNode, type) {
      return type != 'inner'
    }
  },

  data () {
    return {
      headerList: [],
      tableData: []
    }
  },

  created () {

    this.tableData = [
      {
        id: Math.random(),
        name: '小明',
        code: '10001',
        time: '2021-2-10',
        status: '停用',
        children: [
          {
            id: Math.random(),
            name: '小红1',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
          },
          {
            id: Math.random(),
            name: '小红2',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
          }
        ]
      },
      {
        id: Math.random(),
        name: '小明2',
        code: '10001',
        time: '2021-2-10',
        status: '停用',
        children: [
          {
            id: Math.random(),
            name: '小红1',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
          },
          {
            id: Math.random(),
            name: '小红2',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
          }
        ]
      },
      {
        id: Math.random(),
        name: '小明3',
        code: '10001',
        time: '2021-2-10',
        status: '停用',
        children: [
          {
            id: Math.random(),
            name: '小红1',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
          },
          {
            id: Math.random(),
            name: '小红2',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
            children: [
              {
                id: Math.random(),
                name: '小强3',
                code: '10001',
                time: '2021-2-10',
                status: '停用',
              },
              {
                id: Math.random(),
                name: '小强3',
                code: '10001',
                time: '2021-2-10',
                status: '停用',
              },
            ]
          },
          {
            id: Math.random(),
            name: '小红3',
            code: '10001',
            time: '2021-2-10',
            status: '停用',
          },
        ]
      },
    ]

    this.headerList = [
      {
        id: Math.random(),
        label: '名称'
      },
      {
        id: Math.random(),
        label: '编码',
      },
      {
        id: Math.random(),
        label: '记录时间',
      },
      {
        id: Math.random(),
        label: '状态',
      },
      {
        id: Math.random(),
        label: '操作',
      }
    ]
  }
}
</script>

<style lang='less' scoped>
#draggableTable {
  width: 100%;
  height: calc(100% - 110px);
  padding: 20px 20px 0 20px;
  font-size: 14px;

  /deep/ .el-tree {

    .drat-body {
      display: flex;
      justify-content: space-between;
      width: 100%;

      .drat-val-right {
        width: 800px;
      }

      .drat-val-body {
        width: 200px;
      }
    }
    
    .el-tree-node__content {
      padding: 20px 0;
      border-bottom: 1px solid #eee;
      &:hover {
        background-color: #ecf5ff;
      }
    }

    .is-current > .el-tree-node__content {
      background-color: #ecf5ff;
    }
  }

  .drat-header {
    display: flex;
    color: #606266;
    font-weight: 600;
    border-bottom: 1px solid #dcdee3;
    padding: 0 0 10px 24px;

    .drat-item-header {
      width: 200px;
    }

    .drat-name-header {
      width: calc(100% - 800px);
    }
  }
}
</style>

element tree 层级线样式

html

<div
    class="treeWrap"
    style="width:260px;padding-bottom:20px"
>
    <el-tree
        ref="tree"
        :data="tableData"
        :props="defaultProps"
        node-key="id"
        :default-expand-all="true"
        highlight-current
        empty-text="暂无数据"
        class="tree-level-line filter-tree tree-border"
        style="font-size: 14px;"
    >
        <span
          slot-scope="{ node, data }"
          class="flex-1 position-relative">
            <div
                v-show="node.expanded && node.childNodes.length"
                class="tree-level-line-left">
            </div>
            <div class="custom-tree-node">
                <span class="flex-1" style="width: 0;">
                    <small>{{ data.name }}</small>
                </span>
            </div>
        </span>
    </el-tree>
</div>

css

// tree 层级线
.tree-level-line /deep/ .el-tree-node {
    position: relative;
    padding-left: 2px;

    .el-tree-node__content {
        height: unset;
        align-items: baseline;
    }

    .el-tree-node__content > .el-tree-node__expand-icon {
        padding: 2px;
        line-height: 22px;
        font-size: 14px;
    }
}

.tree-level-line /deep/ .el-tree-node__children {
    padding-left: 12px;
}

.tree-level-line /deep/ .el-tree-node :last-child:before {
    height: 38px;
}

.tree-level-line /deep/ .el-tree > .el-tree-node:before {
    border-left: none;
}
.element-ui-view-tree-box .treeWrap {
    overflow: auto;
    width: 100%;
    position: absolute;
    height: calc(100% - 40px);
}

.element-ui-view-tree-box
    .treeWrap
    /deep/
    .tree-level-line.el-tree
    > .el-tree-node:after {
    border: none;
}

.tree-level-line /deep/ .el-tree-node:before {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
}

.tree-level-line /deep/ .el-tree-node:after {
    content: "";
    left: -4px;
    position: absolute;
    right: auto;
    border-width: 1px;
}

.tree-level-line /deep/ .el-tree-node:before {
    border-left: 1px solid #999;
    bottom: 0;
    height: 100%;
    top: -26px;
    width: 1px;
}

.tree-level-line /deep/ .el-tree-node:after {
    border-top: 1px solid #999;
    height: 20px;
    top: 12px;
    width: 8px;
}

.tree-level-line-left {
    display: none;
    position: absolute;
    width: 1px;
    height: calc(100% - 20px);
    border-left: 1px solid #999;
    top: 20px;
    left: -8px;
}

.table-cell-padding-0.el-table td > .cell {
    padding: 0;
}

.node-type-icon {
    color: var(--font-color4);
    transform: scale(0.9);
    font-size: #999 !important;
}
.node-type-icon + small {
    font-size: #999;
}

.node-operate {
    // position: absolute;
    right: 10px;
    .m-icon {
        font-size: 12px;
    }
    .m-icon:hover {
        color: #5f9fff;
    }
}

.el-tree--highlight-current .el-tree-node.is-current > .el-tree-node__content {
    background-color: #e9f1ff;
    .small {
        font-size: 14px;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值