当前位置: 首页 > 知识库问答 >
问题:

vue.js - el-tree 树形结构 怎么添加下级菜单??

慕翰学
2024-07-23

element中el-tree组件,无限制增加下级菜单
为避免一次性请求接口返回数据太多,每次请求接口只能返回该层下一级数据,不会返回下级多层数据

<el-tree
                :data="dataSource"
                show-checkbox
                node-key="id"
                ref="tree"
                lazy
                :load="loadNode"
                default-expand-all
                :props="defaultProps"
                class="knowledgePoint"
                :default-expanded-keys="defaultExpandedKeys"
                :default-expand-all="false"
                :render-after-expand="false"
                :expand-on-click-node="false"
            >
                <template slot-scope="{ node, data }">
                    <span class="custom-tree-node">
                        <el-input
                            v-if="data.isEgdit"
                            size="small"
                            class="egditName"
                            ref="inputVal"
                            @keyup.enter.native="updateName(node, data)"
                            @blur="updateName(node, data)"
                            v-model="input"
                            maxlength="20"
                            placeholder="请输入20个字以内标题">
                        </el-input>
                        <span v-else  @click="setName(data)">{{ node.label }}</span>
                        <span>
                            <a @click="append(data)"> 添加 </a>
                            <a style="margin-left: 8px" @click="删除(node, data)"> Delete </a>
                        </span>
                    </span>
                </template>
            </el-tree>

export default {
    data() {
        return {
            defaultProps: {
                children: 'sub_point_list',
                label: 'name',
                isLeaf: (data) => data.has_child === 0
            },
        }
    },
    methods: {
        //添加下级菜单
        append(data) {
            console.log('data', data)
        
            this.$set(data, 'sub_point_list', [])

            const newChild = { id: id++, name: 'testtest', isEgdit: true, sub_point_list: [] }
            if (!data.sub_point_list) {
                data.sub_point_list = []
            }
            data.sub_point_list.push(newChild)
                // 强制更新视图
              this.$forceUpdate();

              // 展开当前节点
              node.expand();
            this.$nextTick(() => {
                this.$refs.inputVal.focus();
            })
            // this.dataSource = [...this.dataSource]
        },
    }
}

当有下级菜单时,点击箭头展开下级菜单,在点击添加按钮,能正常显示输入框添加菜单 如下图

1.jpg

但是没有下级菜单时,即前边没有小箭头,点击添加按钮,数据也能打印出来,但是却显示不出来输入框,如下图
这里出错的原因在哪里呢?

还有就是当有数据时,点击添加按钮 怎么能直接展开下级并显示出输入框呢?现在是只有点击前边的小箭头展开下级后再点击添加按钮才能显示输入框,求教

2.jpg

共有1个答案

唐康安
2024-07-23

解答

在Element UI的el-tree组件中,当使用lazy属性时,你需要正确地管理节点的加载和展开。对于你的问题,首先要注意的是在添加子节点时,你需要确保父节点被标记为不是叶子节点(即has_child应该不为0),这样它才会显示展开箭头。

此外,当你添加新的子节点时,你需要触发节点的加载,即使你实际上已经直接添加了子节点。这是因为el-treelazy模式下,只有当它认为节点需要加载时(即当节点是叶子节点但又被用户点击展开时),它才会调用load方法。

以下是你需要做的更改:

  1. 确保has_child字段正确设置:在添加子节点之前,确保父节点的has_child字段不为0(或任何表示它不是叶子节点的值)。
  2. 在添加子节点后触发加载:即使你直接添加了子节点,你仍然需要模拟加载过程,以便el-tree知道节点已经加载并且应该展开。
  3. 自动展开新添加的节点:你可以使用this.$refs.tree.setExpandedKeys来展开特定的节点。

以下是修改后的append方法:

append(data) {
  // 确保不是叶子节点
  if (data.has_child === 0) {
    this.$set(data, 'has_child', 1); // 假设1表示有子节点
  }

  // 添加新子节点
  const newChild = { id: id++, name: 'testtest', isEgdit: true, sub_point_list: [] };
  if (!data.sub_point_list) {
    this.$set(data, 'sub_point_list', []);
  }
  data.sub_point_list.push(newChild);

  // 触发节点的加载(即使我们直接添加了子节点)
  this.$refs.tree.load(data);

  // 设置下一个tick以确保DOM已经更新
  this.$nextTick(() => {
    // 展开包含新子节点的节点
    this.$refs.tree.setExpandedKeys([data.id]); // 假设id是唯一的节点键
    this.$refs.inputVal.focus(); // 假设inputVal是对应新节点的输入框引用(这里可能需要调整)
  });
}

注意:上面的代码假设了一些事情,例如id是唯一的节点键,并且inputVal是对应新节点的输入框引用。你可能需要根据你的实际代码进行调整。

另外,关于输入框的引用,由于你是在模板中动态创建的输入框,因此直接使用this.$refs.inputVal可能无法正确引用到新添加的节点的输入框。你可能需要为每个节点创建一个唯一的引用,或者使用其他方法来定位输入框。

 类似资料:
  • 本文向大家介绍Vue.js组件tree实现无限级树形菜单,包括了Vue.js组件tree实现无限级树形菜单的使用技巧和注意事项,需要的朋友参考一下 分享一段用 <ul>和<li>标签实现tree的代码,可能写的不是很好,如果大家有更好的希望分享下。 代码看这里喽: html代码: js代码: 效果图: 本文已被整理到了《Vue.js前端组件学习教程》,欢迎大家学习阅读。 关于vue.js组件的教程

  • 树形结构有两种表示方法:子表表示法(嵌套)和父指针表示法(扁平)。 Tree 将两者进行了整合,输出一个扁平的结构,一个节点既通过 pId(指向父节点的唯一标志)建立与父节点关系,又通过 children(数组,存储子节点的唯一标志)建立与子节点的关系。 一个树形结构,为了方便处理,通常需要具备以下特点: 一个扁平的数组结构很重要,在需要获取某个节点时,可以仅通过一次循环快速找到该节点。Tree

  • el-tree 每次只请求到一级的数据, 返回数据为 当has_child==1时有下级数据,显示小箭头,没有数据时不显示小箭头,如下图 当有数据时点击添加按钮,折叠状态展开,显示出input输入框,此时可以添加新节点,如下图 blur时添加成功,input再转为label显示 编辑时如下图 想找个类似的例子或者写法 求教

  • pre { white-space: pre-wrap; } 本教程向您展示如何附加节点到树形菜单(Tree)。我们将创建一个包含水果和蔬菜节点的食品树,然后添加一些其他水果到已存在的水果节点。 创建食品树 首先,我们创建食品树,代码如下所示:     <div>         <ul id="tt" url="tree_data.json"></ul>     </div> 请注意,树(T

  • pre { white-space: pre-wrap; } 本教程展示如何向带有动态加载特性的树形网格(TreeGrid)添加分页。 创建树形网格(TreeGrid) 启用树形网格(TreeGrid)的分页特性,必须添加 'pagination:true' 属性,这样页面加载时就会向服务器发送 'page' 和 'rows' 参数。     <table title="Products"   

  • el-table中设置tree-props树形数据勾选完成后怎么回显选中状态