antd vue Tree组件,通过key递归获取该节点信息

本文介绍了一个使用树组件的应用案例,展示了如何加载数据并响应选择事件。通过递归过滤方法实现树节点信息的获取。
<template>
  <div class="tzgl_wrap">
        <a-tree
          :tree-data="treeData"
          @select="treeSelect"
          default-expand-all
        >
          <template slot="title" slot-scope="{ title }">
            <span>{{ title }}</span>
          </template>
        </a-tree>
  </div>
</template>

<script>
import {
  MainPageTree
} from '@/api/dwActivityManage'
export default {
  components: {
    Book
  },
  data() {
    return {
      treeData: [],
      treeInfo: {},
    }
  },
  mounted() {
    this.getTreeData()
  },
  methods: {
    getTreeData() {
      MainPageTree().then(res => {
        if (res.code == 200) {
          this.treeData = res.data
          // this.generateList(res.data)
        }
      })
    },
    treeSelect(e) {
    this.recursiveFilter(this.treeData, e[0])
    console.log(this.treeInfo,'======treeInfo')

    },
   // 通过key 获取树节点信息
    recursiveFilter(tree, keys) {
      let data = tree.filter(item => item.key == keys)
      if (data.length != 0) {
        this.treeInfo = data[0]
      } else {
        tree.map(item => {
          if (item.children) {
            //递归循环
            this.recursiveFilter(item.children, keys)
          }
        })
      }
      return data
    },
  }
}
</script>

打印结果:

在这里插入图片描述

<think>我们正在使用Vue 3和Ant Design Vue(Ant Design的Vue实现)的Tree组件。 用户的需求是:点击叶子结点时,如何获取该叶子结点的父级节点。 分析: 在Ant Design VueTree组件中,每个节点被点击时,会触发`select`事件(如果是选择操作)或`check`事件(如果是勾选操作)。但这里用户没有明确是选择还是勾选,根据问题描述,应该是点击事件。 然而,Tree组件并没有直接提供点击节点获取父级节点的方法。我们需要通过Tree组件的实例方法或节点数据来获取。 思路: 1. 我们可以通过Tree组件的`@select`事件(当节点被点击时触发)来获取当前节点key,然后通过Tree组件的方法获取节点。 2. 在Ant Design VueTree组件中,我们可以使用`getParentKey`方法,但注意,Tree组件并没有直接提供这样的方法,所以我们需要自己实现。 另一种方式: 在树形数据中,每个节点通常包含一个`children`属性,表示子节点。我们可以通过遍历树结构来查找父节点。 但是,Ant Design VueTree组件提供了`getNode`方法,通过节点key可以获取节点实例,然后通过节点实例的`parent`属性可以获取节点实例。 步骤: 1.Tree组件添加一个`ref`属性,例如`treeRef`,这样我们可以通过`ref`获取Tree组件实例。 2. 监听节点的点击事件(比如`@select`),在事件处理函数中,我们可以得到当前被点击节点key。 3. 通过组件的`treeRef.value.getNode(key)`方法获取节点实例。 4. 节点实例有一个`parent`属性,指向父节点实例。注意,根节点的父节点为`null`。 注意:`getNode`方法是Tree组件实例的方法,需要先获取Tree组件的实例。 代码框架: 模板部分: ```html <a-tree ref="treeRef" :tree-data="treeData" @select="handleSelect" ... /> ``` 脚本部分(Vue 3 Composition API): ```typescript import { ref } from 'vue'; import { Tree } from 'ant-design-vue'; // 假设我们已经有了treeData export default { setup() { const treeRef = ref<Tree | null>(null); const handleSelect = (selectedKeys: string[], e: { selected: boolean; node: any; event: Event }) => { // 我们只需要选中的第一个key(因为单选,但selectedKeys是数组,通常只有一个) const key = selectedKeys[0]; if (treeRef.value) { const node = treeRef.value.getNode(key); // 获取节点实例 if (node) { const parentNode = node.parent; // 注意:根节点没有父节点,所以parentNode可能为null console.log('父节点:', parentNode); // 父节点的数据在parentNode.dataRef中 if (parentNode) { console.log('父节点数据:', parentNode.dataRef); } } } }; return { treeRef, handleSelect, // ...其他 }; }, }; ``` 注意:在Ant Design Vue中,Tree组件节点实例结构可能有所不同,具体需要查看文档。根据引用内容,我们使用的是`v-model:checkedKeys`,但这里关注的是点击事件,所以用`@select`。 另外,如果用户需要的是勾选事件(`check`),那么事件处理函数会接收到两个参数:`checkedKeys`和`event`,其中`event`对象包含`node`(当前节点)等信息。但是,事件对象中并没有直接提供父节点,所以我们还是需要通过`getNode`方法来获取节点。 对于`check`事件: ```html <a-tree @check="handleCheck" ... /> ``` 处理函数: ```typescript const handleCheck = (checkedKeys: string[], e: { checked: boolean, checkedNodes: any[], node: any, event: Event }) => { const key = e.node.key; // 同样,我们可以通过treeRef.value.getNode(key)来获取节点实例,然后再取父节点 if (treeRef.value) { const node = treeRef.value.getNode(key); if (node && node.parent) { console.log('父节点数据:', node.parent.dataRef); } } }; ``` 但是,在`check`事件中,`e.node`就是当前节点,那么当前节点数据中是否包含父节点信息呢?通常节点数据中不直接包含父节点,所以还是需要借助组件实例的方法。 总结:无论是`select`事件还是`check`事件,获取节点的通用方法是: 1. 获取当前节点key 2. 通过Tree组件的`getNode`方法得到节点实例 3. 通过节点实例的`parent`属性获取节点实例 4. 从父节点实例中取出节点数据(通常是`dataRef`属性) 注意:在Ant Design Vue 3.x中,节点实例的`dataRef`属性就是我们在`treeData`中传入的该节点的原始数据对象。 因此,我们可以在事件处理函数中通过上述步骤获取节点。 另外,如果节点数据中本身就有父节点key(比如我们在生成树数据结构时,每个节点保存了parentId),那么也可以通过这个字段直接获取,但这样需要额外维护,且不是所有数据结构都有。 所以,使用组件提供的方法更为直接。 重要:由于Tree组件是异步加载节点的情况,需要注意在异步加载完成后再使用`getNode`方法。 最后,根据用户的引用内容,他们使用了`v-model:checkedKeys`和`@check`事件,所以用户可能是需要勾选事件中获取节点。因此,我们可以针对`check`事件给出示例。 代码示例(Vue 3 Composition API): 模板: ```html <template> <a-tree ref="treeRef" v-model:checkedKeys="checkedKeys" :tree-data="treeData" checkable @check="handleCheck" /> </template> ``` 脚本: ```typescript <script lang="ts"> import { defineComponent, ref } from 'vue'; import { Tree } from 'ant-design-vue'; export default defineComponent({ setup() { const treeRef = ref<Tree | null>(null); const checkedKeys = ref<string[]>([]); const treeData = ref<any[]>([]); // 树数据,通常从后端获取 const handleCheck = (checkedKeys: string[], e: any) => { // 注意:e参数的结构,在Ant Design Vue中,e.node是当前节点 const currentNode = e.node; // 通过treeRef获取节点实例(注意:e.node可能已经包含了实例信息,但为了统一,我们还是使用treeRef.value.getNode) const key = currentNode.key; if (treeRef.value) { const nodeInstance = treeRef.value.getNode(key); if (nodeInstance && nodeInstance.parent) { const parentNode = nodeInstance.parent; const parentData = parentNode.dataRef; console.log('父节点数据:', parentData); } else { console.log('无父节点(可能是根节点)'); } } }; return { treeRef, checkedKeys, treeData, handleCheck }; }, }); </script> ``` 注意:在`handleCheck`中,`e`参数的类型定义。在TypeScript中,我们可以使用Ant Design Vue提供的类型,但这里简化使用`any`。 另外,Ant Design Vue官方文档中对于`Tree`组件的`getNode`方法描述如下: getNode(key: string | number): TreeNode | null 其中,`TreeNode`类型包含以下属性(非全部): key: string | number; title: string; children: TreeNode[]; parent: TreeNode | null; dataRef: any; // 原始节点数据 因此,我们可以通过`parent`属性获取节点实例。 最后,如果用户的问题是在点击叶子节点获取节点,那么使用`@select`事件也可以同理实现。 但是,注意:`@select`事件在节点被点击时触发(即使不是叶子节点),而`@check`事件在复选框被点击时触发。用户问题中描述的是“点击叶子结点”,所以可能是点击节点本身,而不是复选框。因此,我们需要确认用户意图。 根据问题描述:“点击叶子结点”,那么应该使用`@select`事件。但是,如果用户同时需要复选框操作,则使用`@check`事件。 为了通用性,我们分别给出两种事件的示例。 如果用户只是点击节点(非复选框),则使用`@select`事件: ```html <a-tree ref="treeRef" :tree-data="treeData" @select="handleSelect" /> ``` 处理函数: ```typescript const handleSelect = (selectedKeys: string[], e: any) => { if (selectedKeys.length > 0) { const key = selectedKeys[0]; if (treeRef.value) { const nodeInstance = treeRef.value.getNode(key); if (nodeInstance && nodeInstance.parent) { const parentData = nodeInstance.parent.dataRef; console.log('父节点数据:', parentData); } } } }; ``` 注意:`selectedKeys`是数组,因为Tree支持多选(通过`multiple`属性),但默认是单选。如果是多选,则用户点击节点会切换选中状态,并且`selectedKeys`包含所有选中的节点key。但通常我们只需要当前点击的节点,所以取第一个(如果是单选,数组只有一个元素)。 总结:根据用户的具体事件类型(`select`或`check`)选择相应的事件处理。 最后,由于用户之前的问题中使用了`@check`事件(引用内容中),所以这里重点给出`@check`事件的示例,但同时也说明`@select`事件的处理方式。 生成相关问题: 1. 如何获取Tree组件节点的完整路径(从根节点到当前节点)? 2. 在Ant Design Vue Tree组件中,如何动态更新节点数据? 3. 如何实现Tree组件节点拖拽功能? 4.Tree组件中,如何设置默认展开所有节点? </think>### Vue 3中Ant Design Tree组件点击叶子结点获取父级节点的方法 在Vue 3中使用Ant Design VueTree组件时,可以通过以下步骤实现点击叶子节点获取父级节点: #### 核心方法 1. **使用组件的`@select`事件** 监听节点选择事件,通过`getParentKey`递归查找父节点: ```vue <template> <a-tree :tree-data="treeData" :field-names="{ title: 'name', key: 'id', children: 'children' }" @select="handleNodeSelect" /> </template> <script setup> import { ref } from 'vue'; const treeData = ref([ { id: 'p1', name: '父节点', children: [ { id: 'leaf1', name: '叶子节点1' }, { id: 'leaf2', name: '叶子节点2' } ] } ]); // 递归查找父节点 const findParentKey = (tree, key, parentKey = null) => { for (const node of tree) { if (node.id === key) return parentKey; if (node.children) { const found = findParentKey(node.children, key, node.id); if (found) return found; } } return null; }; const handleNodeSelect = (selectedKeys) => { if (selectedKeys.length === 0) return; const leafKey = selectedKeys[0]; const parentKey = findParentKey(treeData.value, leafKey); console.log('叶子节点Key:', leafKey); console.log('父节点Key:', parentKey); // 输出父节点ID }; </script> ``` 2. **通过节点实例直接获取节点**(推荐) 使用`getNode()`方法获取节点实例,访问`parent`属性: ```vue <template> <a-tree ref="treeRef" :tree-data="treeData" @select="handleNodeSelect" /> </template> <script setup> import { ref } from 'vue'; const treeRef = ref(); const handleNodeSelect = (selectedKeys) => { const leafKey = selectedKeys[0]; const nodeInstance = treeRef.value.getNode(leafKey); if (nodeInstance.parent) { const parentNode = nodeInstance.parent; console.log('父节点数据:', parentNode.dataRef); // 包含完整父节点数据 console.log('父节点ID:', parentNode.key); } }; </script> ``` #### 关键说明 1. **`getNode()`方法** - 需通过`ref`获取Tree组件实例 - 返回节点对象包含: ```typescript { key: string, // 节点key dataRef: object, // 原始节点数据 parent: NodeInstance, // 父节点实例 children: [] // 子节点数组 } ``` 2. **注意事项**: -节点的`parent`属性为`null` - 使用`dataRef`可获取初始化时的完整节点数据 - 半选状态节点可通过`node.halfChecked`识别[^1] #### 完整示例 ```vue <template> <a-tree ref="treeRef" :tree-data="treeData" :field-names="{ title: 'name', key: 'id' }" @select="handleNodeSelect" /> </template> <script setup> import { ref } from 'vue'; const treeRef = ref(); const treeData = ref([...]); // 树结构数据 const handleNodeSelect = (selectedKeys) => { if (!selectedKeys.length) return; const node = treeRef.value.getNode(selectedKeys[0]); if (!node.parent) { console.log('当前是根节点'); return; } const parentData = node.parent.dataRef; console.log('父节点名称:', parentData.name); console.log('父节点ID:', parentData.id); }; </script> ``` ### 相关技术要点 1. **数据结构要求**: ```javascript // 节点必须包含key和children字段 const node = { id: 'unique_key', // 通过field-names映射为key name: '显示文本', children: [...] // 子节点数组 } ``` 2. **事件选择建议**: - `@select`:点击节点时触发(适合导航场景) - `@check`:勾选复选框时触发(适合权限选择场景) - `@expand`:展开/折叠时触发 3. **动态更新父节点状态**: ```javascript // 修改父节点数据示例 const updateParent = (parentKey) => { const parentNode = treeRef.value.getNode(parentKey); parentNode.dataRef.name = '修改后的名称'; }; ``` [^1]: 关于树状组件半选状态的初始处理逻辑,详见引用内容。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值