el-tree的一些使用

 ​​​​​​​

问题 

做项目的时候有一个需求就是,当点击新建的时候就往树结构中添加一个主题,如有没有选中节点,就在根节点最后面push一个,如果有选中的节点,要先看是父节点还是子节点,如果是父节点,就在父节点的子节点最后push一个节点,如果选中的是子节点,就在该子节点的后面添加一个同级的子节点

 

   <el-tree
          ref="treeRef"
          :default-expanded-keys="[1]" //默认展开id=1的节点
          :data="dataSource" //树的数据
          node-key="id" //每个树节点用来作为唯一标识的属性,整棵树应该是唯一的
          show-checkbox //展示复选框
          check-strictly //父子节点不关联
          :expand-on-click-node="false" //只有在点击复选框时才会选中节点
        >
          <template #default="{ node, data }">
            <div class="custom-tree-node">
              <span class="icon-box">
                <i
                  class="iconfont icon-a-tubiao5"
                  v-if="data.children || (data.children && data.showInputBox)"
                ></i>
                <i class="iconfont icon-yuandianxiao" v-else></i>
              </span>
              <span>{{ node.label }}</span>
              <!--input输入-->
              <div class="input-box" v-if="ifAddInputVisible(data)">
                <el-input
                  clearable
                  placeholder="请输入文件名"
                  v-model="topic"
                ></el-input>
                <div class="input-icon">
                  <i
                    class="iconfont icon-cuowu"
                    @click="inputCanel(data, node)"
                  ></i>
                  <i
                    class="iconfont icon-duihao"
                    @click="inputConfirm(data, node)"
                  ></i>
                </div>
              </div>
            </div>
          </template>
        </el-tree>

解决方案 

  1.  先看有没有选中的节点(在el-tree中有一个方法,getCheckedNodes()   返回当前选中节点的数据 )
  2. 看选中的是父节点还是子节点 (利用getCheckedNodes() 方法,判断是否有children,如果有就是父节点,如果没有就是子节点)
  3. 如果的是父节点,直接在后面push
  4. 如果的是子节点,就要先找到子节点的父节点,然后找到当前子节点在父节点中的位置,然后在这个位置后面添加一个新的子节点

 代码

const addTheme = () => {
  // 获取当前选中节点的数据
  const currentNodeData = treeRef.value.getCheckedNodes();
  if (currentNodeData.length > 0) {
    //有选中的节点
    const currentNode = currentNodeData[0];
    const parentNode = findParentNode(dataSource.value, currentNode.id);
    if (currentNode.children) {
      //选中的是父节点
      // 直接向 children 数组添加新节点
      parentNode.children.push({
        label: "",
        showInputBox: true,
        id: generateUniqueId(),//给节点添加一个唯一的id
      });
      //展开选中的父节点
      const newNode = treeRef.value.getNode(currentNode.id);
      newNode.expanded = true;
    } else {
      //选中的是子节点
      // 在父节点的 children 数组中插入新节点
      const index = parentNode.children.findIndex(
        (node) => node === currentNode
      );
      if (index > -1) {
        parentNode.children.splice(index + 1, 0, {
          label: "",
          showInputBox: true,
          id: generateUniqueId(),
        });
      }
    }
  } else {
    // 没有选中节点时,在根节点中添加新节点
    dataSource.value.push({
      label: "",
      showInputBox: true,
      children: [],
      id: generateUniqueId(),
    });
  }
};

利用递归获取到当前节点的父节点

//获取选中节点的父节点
const findParentNode = (nodes, targetNodeId) => {
  for (const node of nodes) {
    if (node.id === targetNodeId) {
      return node; // 当前节点是父节点,直接返回
    }
    if (node.children) {
      const childNode = findParentNode(node.children, targetNodeId);
      if (childNode) {
        return node; // 当前节点是子节点,返回当前节点的父节点
      }
    }
  }

  return null; // 没有找到点击节点的父节点
};

 输入框后面的 x 和✓

const inputConfirm = (node) => {
  if (topic.value.trim() === "") {
    // 输入为空时给出提示
    ElMessage.warning("请输入节点名称");
    return;
  }
  node.showInputBox = false; // 隐藏输入框
  node.label = topic.value; // 设置节点名称
  topic.value = ""; // 清空输入框内容
};
//取消新建
const inputCanel = (data, node) => {
  // 取消输入,移除节点
  const parentNode = node.parent;
  const childrenArray = parentNode.data.children || parentNode.data; // 获取父节点的子节点数组
  const index = childrenArray.indexOf(data); // 查找要删除节点的索引
  if (index > -1) {
    childrenArray.splice(index, 1); // 从数组中移除节点
  }
  topic.value = ""; // 清空输入框内容
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值