vue + elementUI 手动控制 tree 组件节点的展开状态

本文介绍如何在Vue结合ElementUI中实现Tree组件的一键展开与收起功能,通过遍历Tree节点并修改其展开状态,提升用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue + elementUI 手动控制tree组件节点的展开状态

在日常工作中,会时常接触到 tree 结构的目录,在手动合并目录之后,不想一个一个再去展开,就需要一个按钮可以帮助用户一键展开 tree 结构,顺着这个需求寻求解决方法

解决方案如下:

<template>
  <div id="app">
    <el-button ref="openBtn" @click="open">展开</el-button>
    <el-button ref="closeBtn" @click="close">收起</el-button>
    <el-tree 
      :data="data" 
      ref="tree" 
      node-key="id" 
      :props="defaultProps" 
    />
  </div>
</template>

<script>

export default {
  name: 'App',
  components: {
    // HelloWorld
  },
  data() {
    return {
      data: [{
          id: 1,
          label: '一级 1',
          children: [{
            id: 11,
            label: '二级 1-1',
            children: [{
              id: 111,
              label: '三级 1-1-1'
            }]
          }]
        }, {
          id:2,
          label: '一级 2',
          children: [{
            id: 21,
            label: '二级 2-1',
            children: [{
              id: 211,
              label: '三级 2-1-1'
            }]
          }, {
            id: 22,
            label: '二级 2-2',
            children: [{
              id: 221,
              label: '三级 2-2-1'
            }]
          }]
        }, {
          id: 3,
          label: '一级 3',
          children: [{
            id: 31,
            label: '二级 3-1',
            children: [{
              id: 311,
              label: '三级 3-1-1'
            }]
          }, {
            id: 32,
            label: '二级 3-2',
            children: [{
              id: 321,
              label: '三级 3-2-1'
            }]
          }]
        }],
        defaultProps: {
          children: 'children',
          label: 'label'
        },
    }
  },
   methods: {
   	  // 展开按钮
      open() {
      	// 控制按钮点击之后失焦
        this.$refs.openBtn.$el.blur()
        for(let key in this.$refs.tree.store.nodesMap) {
          console.log(this.$refs.tree.store.nodesMap[key]);
          this.$refs.tree.store.nodesMap[key].expanded = true
        }
      },
      // 收起按钮
      close(){
      	// 控制按钮点击之后失焦
        this.$refs.closeBtn.$el.blur()
        for(let key in this.$refs.tree.store.nodesMap) {
          this.$refs.tree.store.nodesMap[key].expanded = false
        }
      }
    }
}
</script>
### Vue3 中基于 Element Plus 的树形结构实现 在 Vue3 和 Element Plus(Element UI 的 Vue3 版本)中,可以通过 `el-tree` 组件轻松实现树形结构的数据展示。以下是具体实现方式以及父子联动功能的说明。 #### 数据准备与树形转换 为了构建树形结构,通常需要将扁平化的数据转化为嵌套形式。可以使用类似于引用中的 `convertToTree` 方法[^1]来进行数据处理: ```javascript // 转换树形菜单 function convertToTree(arr) { const map = {}; arr.forEach((item) => { map[item.id] = { ...item, children: [] }; }); const treeData = []; arr.forEach((item) => { if (item.parentId && map[item.parentId]) { map[item.parentId].children.push(map[item.id]); } else { treeData.push(map[item.id]); } }); return treeData; } ``` 此函数会返回一个适合用于 `el-tree` 或其他树形组件渲染的嵌套对象数组。 --- #### 树形表格配置 在 Vue3 中,`<el-table>` 支持树形展开的功能,通过设置属性 `row-key` 和 `lazy` 可以进一步增强性能和灵活性。以下是一个完整的示例代码片段: ```vue <template> <div> <!-- 表格 --> <el-table :data="treeTableData" row-key="id" default-expand-all border style="width: 100%" @selection-change="handleSelectionChange"> <!-- 多选框列 --> <el-table-column type="selection" width="55"></el-table-column> <!-- 自定义列 --> <el-table-column prop="name" label="名称" width="200"></el-table-column> <el-table-column prop="description" label="描述"></el-table-column> </el-table> <!-- 全选按钮 --> <el-button @click="toggleAllSelection">全选/取消</el-button> </div> </template> <script> import { ref } from 'vue'; export default { setup() { // 扁平化数据源 const flatData = [ { id: 1, parentId: null, name: "根节点", description: "这是根节点" }, { id: 2, parentId: 1, name: "子节点1", description: "属于根节点下的第一个子节点" }, { id: 3, parentId: 1, name: "子节点2", description: "属于根节点下的第二个子节点" }, { id: 4, parentId: 2, name: "孙节点1", description: "属于子节点1的第一个孙节点" } ]; // 转换成树形结构 function convertToTree(data) { const map = {}; data.forEach((item) => { map[item.id] = { ...item, children: [] }; }); const result = []; data.forEach((item) => { if (item.parentId && map[item.parentId]) { map[item.parentId].children.push(map[item.id]); } else { result.push(map[item.id]); } }); return result; } const treeTableData = ref(convertToTree(flatData)); // 当前选中的行集合 let selectedRows = []; // 切换单个或多行的选择状态 function handleSelectionChange(selection) { selectedRows = selection; } // 控制全选逻辑 function toggleAllSelection() { const tableRef = this.$refs.table; // 获取 el-table 实例 if (!selectedRows.length || selectedRows.length !== treeTableData.value.flat().length) { selectedRows = treeTableData.value.flat(); tableRef.clearSelection(); // 清除原有选择 selectedRows.forEach(row => tableRef.toggleRowSelection(row, true)); } else { tableRef.clearSelection(); } } return { treeTableData, handleSelectionChange, toggleAllSelection }; } }; </script> ``` 上述代码实现了以下几个核心功能: - **树形数据展示**:利用 `convertToTree` 函数将原始数据转为嵌套结构并绑定至 `<el-table>`。 - **多选框支持**:通过 `type="selection"` 添加多选框,并监听 `@selection-change` 更新已选项。 - **全选控制**:提供了一个按钮切换所有行的选中状态[^2]。 --- #### 父子联动机制 如果希望实现父子节点之间的勾选联动,可以在初始化时启用 `show-checkbox` 并禁用严格模式 (`check-strictly`)。例如,在单独使用的 `<el-tree>` 场景下可这样配置[^3]: ```html <el-tree :data="treeData" show-checkbox node-key="id" check-strictly=false /> ``` 对于表格式布局,则需手动维护父子关系,确保每次更新父节点状态时同步调整其子节点状态--- ### 注意事项 1. 若涉及大量数据或复杂场景,建议开启懒加载(`lazy=true`)优化性能。 2. 动态接口请求应结合 `load` 方法完成异步加载操作。 3. 对于跨版本迁移(如从 Vue2 升级),注意 API 差异可能导致部分行为变化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值