element ui tree树形控件 编辑,新增及删除

element ui tree树形控件 编辑,新增及删除。效果图如下:

可实现对一、二、三级目录的增删改,以及页面样式实现。

<template>代码

<template>
  <div>
    <!-- 导航菜单 -->
    <div class="custom-tree-container">
      <div class="block">
        <!-- <p>使用 scoped slot</p> -->
        <div class="allC" @click="handleAllCase">
          <i class="el-icon-link"></i><span class="allCase">所有用例</span>
        </div>
        <el-tree
          :data="data"
          show-checkbox
          node-key="id"
          :expand-on-click-node="false"
          @node-drag-start="handleDragStart"
          @node-drag-enter="handleDragEnter"
          @node-drag-leave="handleDragLeave"
          @node-drag-over="handleDragOver"
          @node-drag-end="handleDragEnd"
          @node-drop="handleDrop"
          @node-click="myEvent"
          draggable
          :allow-drop="allowDrop"
          :allow-drag="allowDrag"
        >
          <span
            class="custom-tree-node"
            slot-scope="{ node, data }"
            @mouseenter="onMouseOver($event)"
            @mouseleave="onMouseOut($event)"
          >
            <span v-if="!data.isEdit">{{ node.label }}</span>
            <span class="isEdit">
              <!-- 编辑状态 -->
              <div v-if="data.isEdit">
                <el-input
                  v-model="data.label"
                  autofocus
                  size="mini"
                  :ref="'slotTreeInput' + data[id]"
                  @blur.stop="handleInput(node, data)"
                  @keyup.enter.native="handleInput(node, data)"
                ></el-input>
              </div>
              <!-- 非编辑状态 -->
              <div v-else>
                <!-- 名称: 新增节点增加class(is-new) -->
                <span
                  :class="[
                    data[id] < NODE_ID_START ? 'is-new' : '',
                    'comp-tr-node--name',
                  ]"
                >
                </span>
              </div>

              <span class="comp-tr-node--btns" v-show="false">
                <el-dropdown trigger="click" @visible-change="handleDropdown">
                  <i class="el-icon-more"></i>
                  <el-dropdown-menu slot="dropdown">
                    <el-dropdown-item @click.native="() => append(node, data)">
                      <i class="el-icon-circle-plus-outline"></i
                      >新增</el-dropdown-item
                    >
                    <el-dropdown-item @click.native="handleEdit(node, data)"
                      ><i class="el-icon-edit"></i>编辑</el-dropdown-item
                    >
                    <el-dropdown-item @click.native="() => remove(node, data)"
                      ><li class="el-icon-delete"></li>
                      删除</el-dropdown-item
                    >
                  </el-dropdown-menu>
                </el-dropdown>
              </span>
            </span>
          </span>
        </el-tree>
        <i class="el-icon-plus"
          ><span @click="handleNewMoudle">新建模块</span></i
        >
      </div>
    </div>
  </div>
</template>

         JS代码

<script>
let id = 1000;
export default {
  data() {
    const data = [
      {
        id: 1,
        label: "用例管理",
        children: [
          {
            id: 4,
            label: "用例first",
            children: [
              {
                id: 5,
                label: "用例second",
              },
              {
                id: 6,
                label: "用例three",
              },
            ],
          },
        ],
      },
      {
        id: 2,
        label: "用例管理",
        children: [
          {
            id: 7,
            label: "用例first",
          },
          {
            id: 8,
            label: "用例second",
          },
        ],
      },
      {
        id: 3,
        label: "用例管理",
        children: [
          {
            id: 9,
            label: "用例first",
          },
          {
            id: 10,
            label: "用例second",
          },
        ],
      },
    ];
    return {
      data: JSON.parse(JSON.stringify(data)),
      currentEle: null, //操作下拉列表 当前图表元素 省略号
      dropdownShow: false, //下拉列表当前显示状态
      setTree: [], // tree数据
      id: "id", // id对应字段
      MAX_LEVEL: 3, // 设定最大层级
      NODE_ID_START: 0, // 新增节点id,逐次递减
      startId: null,
      //页面可拖拽
      defaultProps: {
        children: "children",
        label: "label",
      },
    };
  },
  props: {
    bool: {
      type: Boolean,
      default: false,
    },
  },
  created() {
    // 初始值
    this.startId = this.NODE_ID_START;
  },

  methods: {
    //所有用例列表接口
    handleAllCase() {},
    //el-tree点击事件
    myEvent(d1, d2, d3) {
      this.$emit("myEvent", d1.id);
    }, //d1.label
    //下拉列表
    handleDropdown(v) {
      this.dropdownShow = v;
      if (v) return;
      this.currentEle.style.cssText += "display:none";
    },
    //增删改鼠标移入移出隐藏显示
    //鼠标移入
    onMouseOver: function (event) {
      event.target.parentElement.querySelector(
        ".comp-tr-node--btns"
      ).style.cssText += "display:block";
      this.currentEle = event.target.parentElement.querySelector(
        ".comp-tr-node--btns"
      );
    },
    //鼠标移出
    onMouseOut: function (event) {
      if (this.dropdownShow) return;
      event.target.parentElement.querySelector(
        ".comp-tr-node--btns"
      ).style.cssText += "display:none";
    },
    //新增一级目录模块点击事件
    handleNewMoudle() {
      this.data.push({
        id: id++,
        label: "未命名模块",
        children: [],
        isEdit: true,
      });
    },
    //新增按钮
    append(node, data) {
      if (node.level >= this.MAX_LEVEL) {
        this.$message.warning(
          "当前目录已达到" + this.MAX_LEVEL + "级,无法新增!"
        );
        return false;
      }
      //新定义一个对象
      const newChild = {
        id: id++,
        label: "未命名模块",
        children: [],
        isEdit: true,
      };
      if (!data.children) {
        this.$set(data, "children", []);
      }
      data.children.push(newChild);
      //新增子节点到3级
      console.log(node, data);

      this.$nextTick(() => {
        if (this.$refs["slotTreeInput" + data[this.id]]) {
          this.$refs["slotTreeInput" + data[this.id]].$refs.input.focus();
        }
      });
    },
    //删除按钮
    remove(node, data) {
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex((d) => d.id === data.id);
      children.splice(index, 1);
    },
       
    //编辑按钮
    handleInput(node, data) {
      // 修改节点
      console.log(node, data);
      // 退出编辑状态
      if (data.isEdit) {
        this.$set(data, "isEdit", false);
      }
    },
    handleEdit(node, data) {
      // 编辑节点
      console.log(node, data);
      // 设置编辑状态
      if (!data.isEdit) {
        this.$set(data, "isEdit", true);
      }

      // 输入框聚焦
      this.$nextTick(() => {
        if (this.$refs["slotTreeInput" + data[this.id]]) {
          this.$refs["slotTreeInput" + data[this.id]].$refs.input.focus();
        }
      });
    },

    //拖拽点击事件
    handleDragStart(node, ev) {
      // console.log("drag start", node);
    },
    handleDragEnter(draggingNode, dropNode, ev) {
      //console.log("tree drag enter: ", dropNode.label);
    },
    handleDragLeave(draggingNode, dropNode, ev) {
      // console.log("tree drag leave: ", dropNode.label);
    },
    handleDragOver(draggingNode, dropNode, ev) {
      // console.log("tree drag over: ", dropNode.label);
    },
    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      // console.log("tree drag end: ", dropNode && dropNode.label, dropType);
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      // console.log("tree drop: ", dropNode.label, dropType);
    },
    //拖拽点击事件
    allowDrop(draggingNode, dropNode, type) {
      if (dropNode.data.label === "二级 3-1") {
        return type !== "inner";
      } else {
        return true;
      }
    },
    allowDrag(draggingNode) {
      return draggingNode.data.label.indexOf("三级 3-2-2") === -1;
    },
  },
};
</script>

    CSS代码

 

<style lang="less" scoped>
.allC {
  margin-left: 21px;
  margin-bottom: 5px;
  i {
    color: #c0c4cc;
  }
  .allCase {
    margin-left: 8px;
    color: #606266;
    font-size: 14px;
  }
}

.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.el-tree {
  height: 100%;
  .isEdit {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    .el-input {
      width: 100px;
      height: 5px;
    }
  }
}
.el-icon-plus {
  margin: 10px 0 0 22px;
  color: #606266;
  font-size: 14px;
  span {
    margin-left: 10px;
    font-size: 14px;
  }
}
</style>


版权声明:本文为yuhan___原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。