ElementUI 树形组件 el-tree 实现增删改(同级、子集的增加)

587 阅读1分钟

实现效果图如下所示:

image.png

实际项目中使用,根据实际情况可参考挑选。代码如下:

<template>
  <div class="tree-meum">
    <el-tree :data="data" :highlight-current="true" :default-expand-all="true" :expand-on-click-node="false"
      @node-click="(data) => onNodeClick(data, false)" node-key="id" :filter-node-method="filterNode" ref="tree">
      <template v-slot="{ node, data }" class="show-hide custom-tree-node">
        <span class="show-hide custom-tree-node">
          <!-- <span>{{ data.name }}</span> -->
          <!-- <span class="tree_node_label">{{showOrEdit(data)}}</span> -->
          <span v-if="data.isEdit" class="inputsty">
            <input ref="getfocus" type="text" class="node_input" :value=data.name
              @blur="(ev) => edit_sure(ev, node, data)" @keyup.enter.native="(ev) => submitForm(ev, node, data)" />
          </span>
          <span v-else>{{ data.name }}</span>
          <el-dropdown class="buttonList">
            <span :class="['more', data.isEdit ? 'more_none' : '']">
              ···
            </span>
            <template #dropdown>
              <el-dropdown-item @click="() => insertAfter(node, data)">
                <el-button type="text" size="mini">
                  同级增加
                </el-button>
              </el-dropdown-item>
              <el-dropdown-item @click="() => append(node, data)">
                <el-button type="text" size="mini">
                  子集增加
                </el-button>
              </el-dropdown-item>
              <el-dropdown-item @click="() => remove(node, data)">
                <el-button type="text" size="mini">
                  删除
                </el-button>
              </el-dropdown-item>
              <el-dropdown-item @click="(ev) => nodeEdit(ev, store, data)">
                <el-button type="text" size="mini">
                  编辑
                </el-button>
              </el-dropdown-item>
            </template>
          </el-dropdown>
        </span>
        <!-- <span class="tree_node_label">{{showOrEdit(data)}}</span> -->

      </template>
    </el-tree>
  </div>
</template>

<script>
import { componentTree, componentTreeCreate,componentTreeUpdate, treeDeleteComponentTreeId } from '@/api/busin'
export default {
  components: {
  },
  props: {
  },
  data() {
    return {
      data: [],
      filterText: '',
    }
  },
  created() {
    this.getTree()//初始化加载树
  },
  methods: {
    async getTree() {
      let result = await componentTree({})
      this.data = result.data
    },
    //添加同级节点
    insertAfter(node, data) {
      const nodeList = node.parent.childNodes;
      const curArr = node.parent.data.children || node.parent.data;
      const index = curArr.findIndex(d => d.id === data.id) + 1;
      new Promise((resolve, reject) => {
        const newBrother = { id: data.parent_id, name: "", children: [], isEdit: true, type: 'add' };
        curArr.splice(index, 0, newBrother);
        resolve();
      }).then(res => {
        nodeList[index].checked = true;
        this.$nextTick(() => {
          this.$refs.getfocus.focus();
        })
      });

    },
    append(node, data) {
      const newChild = { id: data.id, name: '', children: [], isEdit: true, type: 'add' };
      if (!data.children) {
        this.$set(data, 'children', []);
      }
      data.children.push(newChild);
      this.$nextTick(() => {
        this.$refs.getfocus.focus();
      })
    },
    nodeEdit(ev, store, data) {
      data.isEdit = true;
      this.$nextTick(() => {
        this.$refs.getfocus.focus();
      });
    },
    //失焦事件
    async edit_sure(ev, node, data) {
      const $input =
        ev.target.parentNode.parentNode.querySelector("input") ||
        ev.target.parentElement.parentElement.querySelector("input");
      if (!$input) {
        return false;
      } else if ($input.value == '') {
        this.remove(node, data, 1)
      } else {//赋值value
        if (data.isEdit) {
          if (data.type) {//增加
            const res = await componentTreeCreate({ parent_id: data.id, name: $input.value })
            if (res.data) {
              data.name = $input.value;
              data.isEdit = false;
              this.getTree()
            }
          } else {//修改
            const res = await componentTreeUpdate({ id: data.id, name: $input.value })
            if (res.data) {
              data.name = $input.value;
              data.isEdit = false;
              this.getTree()
            }
          }
        }
      }
    },
    async remove(node, data, type) {
      const parent = node.parent;
      const children = parent.data.children || parent.data;
      const index = children.findIndex(d => d.id === data.id);
      if (type == 1) {
        return children.splice(index, 1);
      }
      await this.$messageBox.confirm(`您确定要删除吗`, '提示')
      const res = await treeDeleteComponentTreeId(data.id)
      if (res.data) {
        this.getTree()
        // children.splice(index, 1);
      }
    },
    // 树节点 点击事件
    async onNodeClick(data, stopRequestTree) {
    },
    submitForm(ev, node, data) {
      this.edit_sure(ev, node, data)
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    }
  },
}
</script>
<style>
.show-hide {
  width: 100%;
  position: relative;
}

.buttonList {
  position: absolute;
  right: 8px;
  display: none;
}

.more {
  font-size: 16px;
}

.more_none {
  display: none;
}

.buttonList span {
  padding: 0px 3px;
}

.node_input {
  width: 80px;
}

.inputsty {
  color: #000;
}

.show-hide:hover :nth-child(2) {
  display: inline-block !important;
}

.el-dropdown-menu__item {
  padding: 0px 14px;
  cursor: pointer;
}

.el-dropdown-menu__item:not(.is-disabled):focus {
  background-color: rgb(145, 156, 185, 0.1);
}

.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content {
  color: #fff;
}

</style>