我们可以在element ui 官方文档上看到提供的新增及删除方法,大多数人都想要它的可编辑状态,自己优化了一下,写了关于树形控件tree,新增顶级节点及当前节点可编辑删除操作,以及子节点的新增
效果图如下所示
在这里插入图片描述
代码如下:

<template>
	<div>
	<el-button
          class="addBtn"
          type="primary"
          size="small"
          @click="openAddTop"
          >添加顶级节点</el-button
        >
        <el-input placeholder="输入关键字进行过滤" v-model="filterText">
        </el-input>
		<el-tree
            ref="SlotTree"
            :data="setTree"
            :props="defaultProps"
            :expand-on-click-node="false"
            highlight-current
            :node-key="NODE_KEY"
          >
            <div class="comp-tr-node" slot-scope="{ node, data }">
              <!-- 编辑状态 -->
              <template v-if="node.isEdit">
                <el-input
                  v-model="data.label"
                  autofocus
                  size="mini"
                  :ref="'slotTreeInput' + data[NODE_KEY]"
                  @blur.stop="handleInput(node, data)"
                  @keyup.enter.native="handleInput(node, data)"
                ></el-input>
              </template>
              <!-- 非编辑状态 -->
              <template v-else>
                <!-- 名称: 新增节点增加class(is-new-->
                <span
                  :class="[
                    data[NODE_KEY] < NODE_ID_START ? 'is-new' : '',
                    'comp-tr-node--name',
                  ]"
                >
                  {{ node.label }}
                </span>

                <!-- 按钮 -->
                <span class="comp-tr-node--btns">
                  <!-- 新增 -->
                  <el-button
                    type="text"
                    size="mini"
                    @click="appendChild(node, data)"
                  >新增</el-button>

                  <!-- 编辑 -->
                  <el-button
                    size="mini"
                    type="text"
                    @click="handleEdit(node, data)"
                  >编辑</el-button>

                  <!-- 删除 -->
                  <el-button
                    size="mini"
                    type="text"
                    @click="handleDelete(node, data)"
                  >删除</el-button>
                </span>
              </template>
            </div>
          </el-tree>
          <el-dialog
      		:close-on-click-modal="false"
      		:visible.sync="addDialogVisible"
      		width="30%"
      		top="5vh"
      		:show-close="true"
      		:before-close="addHandleClose"
      		:title="addDialogTitle == 'edit' ? '编辑名称' : '新增名称'"
    		>
      		<el-form
        		:model="addForm"
        		:rules="addRules"
        		label-width="80px"
        		ref="addRef">
				<el-form-item label="名称" prop="name">
          			<el-input size="medium" v-model="addForm.name" placeholder="名称" />
        		</el-form-item>
      		</el-form>
      		<span class="dialog-footer">
        		<el-button size="small" @click="addHandleClose">取 消</el-button>
        		<el-button size="small" type="primary" @click="addData">确 定</el-button>
      		</span>
    </el-dialog>
	</div>
</template>
<script>
	export default {
		data() {
			return {
				addType: 1,
      			addNode:'',
      			startId: null,
      			setTree: [], // tree数据
      			NODE_KEY: "id", // id对应字段
      			MAX_LEVEL: 3, // 设定最大层级
      			NODE_ID_START: 0, // 新增节点id,逐次递减
      			startId: null,
      			defaultProps: {
        			// 默认设置
        			children: "children",
        			label: "label",
      			},
      			addDataList: "",
      			addForm: {
        			name: "",
      			},
      			addRules: {
        			name: [{ required: true, message: "请输入名称", trigger: "blur" }],
      			},
      			addDialogTitle: "new",
      			addDialogVisible: false,
      			// 之前遗忘了这个参数 重新补发
      			**initParam: {
        			// 新增参数
        			name: "",
        			id: 0,
        			children: [],
      			},**
			}
		},
		created() {
    		// 初始值
    		this.startId = this.NODE_ID_START;
  		},
  		methods: {
  			handleDelete(_node, _data) {
      			// 删除节点
      			console.log(_node, _data);
      			// 判断是否存在子节点
      			if (_data.children && _data.children.length !== 0) {
        			this.$message.error("此节点有子级,不可删除!");
        			return false;
      			} else {
        			// 删除操作
        			let DeletOprate = () => {
          				this.$nextTick(() => {
            				if (this.$refs.SlotTree) {
              					this.$refs.SlotTree.remove(_data);
              					this.$message.success("删除成功!");
            				}
          				});
        			};
        			// 二次确认
        			let ConfirmFun = () => {
          				this.$confirm("是否删除此节点?", "提示", {
            				confirmButtonText: "确认",
            				cancelButtonText: "取消",
            				type: "warning",
         				 })
            				.then(() => {
              					DeletOprate();
            				})
            				.catch(() => {});
        		};
        		// 判断是否新增: 新增节点直接删除,已存在的节点要二次确认
        		_data[this.NODE_KEY] < this.NODE_ID_START
          			? DeletOprate()
          			: ConfirmFun();
      			}
    		},
    		handleInput(_node, _data) {
      			// 修改节点
      			console.log(_node, _data);
      			// 退出编辑状态
      			if (_node.isEdit) {
        			this.$set(_node, "isEdit", false);
      			}
    		},
    		handleEdit(_node, _data) {
      			// 编辑节点
      			console.log(_node, _data);
      			// 设置编辑状态
      			if (!_node.isEdit) {
        			this.$set(_node, "isEdit", true);
      			}
      			// 输入框聚焦
      			this.$nextTick(() => {
        			if (this.$refs["slotTreeInput" + _data[this.NODE_KEY]]) {
          				this.$refs["slotTreeInput" + _data[this.NODE_KEY]].$refs.input.focus();
        			}
      			});
    		},
    		// 新增子级节点打开事件
    		appendChild(node,data) {
      			this.addForm.name = "";
      			this.addDialogVisible = true;
     		 	this.addDialogTitle = "new";
      			this.addDataList = data;
      			this.addNode=node
      			this.addType = 2;
    		},
    		// 新增子级节点
    		handleAdd(_node, _data,_name) {
      			// 新增节点
      			console.log(_node, _data);
      			// 判断层级
      			if (_node.level >= this.MAX_LEVEL) {
        			this.$message.warning("当前已达到" + this.MAX_LEVEL + "级,无法新增!");
        			return false;
      			}
      			// 参数修改
      			let obj = JSON.parse(JSON.stringify(this.initParam)); // copy参数
      			obj.id = _data[this.NODE_KEY]; // 父id
      			obj[this.NODE_KEY] = ++this.startId; // 节点id:逐次递减id
      			obj.label=_name
      			// 判断字段是否存在
      			if (!_data.children) {
        			this.$set(_data, "children", []);
      			}
      			// 新增数据
      			_data.children.push(obj);
      			// 展开节点
      			if (!_node.expanded) {
        			_node.expanded = true;
      			}
    		},
    		// 新增顶级结点打开事件
    		handleAddTop() {
      			// 添加顶部节点
      			let obj = JSON.parse(JSON.stringify(this.initParam)); // copy参数
      			console.log(obj);
      			obj[this.NODE_KEY] = ++this.startId; // 节点id:逐次递减id
      			obj.label = this.addForm.name;
      			console.log(obj.label)
      			this.setTree.push(obj);
    		},
    		// 新增顶级结点
    		openAddTop() {
      			this.addForm.name = "";
      			this.addDialogVisible = true;
      			this.addDialogTitle = "new";
      			this.addType = 1;
    		},
    		// 点击确定 新增子级菜单
    		addData() {
      			var t = this;
      			this.$refs.addRef.validate(async (valid) => {
        			if (valid) {
          				if (t.addType == 1) {
            				t.handleAddTop();
            				this.addDialogVisible = false;
          				} else if (t.addType == 2) {
            				const obj = JSON.parse(JSON.stringify(t.addForm));
           					 // 需要判断新增还是编辑
            				t.handleAdd(t.addNode,t.addDataList,obj.name)
            				this.addDialogVisible = false;
          				}
        			} else {
          				console.log("error submit!!");
          				return false;
        			}
      			});
    		},
    		addHandleClose() {
      			this.addDialogVisible = false;
      			this.$refs.addRef.resetFields();
    		},
  		}
  		
	}
</script>

我这里主要用到弹框来新增顶级节点,自己输入名称,完成节点新增
效果图如下
在这里插入图片描述

在这里插入图片描述
每个子节点以及顶级节点都会运用弹框来新增节点对象

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐