树的自动展开和懒加载

229 阅读1分钟
<template>
  <el-tree
    :data="treeData"
    :props="treeProps"
    :load="lazyLoad"
    ref="tree"
    @node-click="handleNodeClick"
  ></el-tree>
</template>

<script>
import 'element-ui/lib/theme-chalk/tree.css';
import { Tree } from 'element-ui';

export default {
  components: {
    ElTree: Tree
  },
  data() {
    return {
      treeData: [] // 初始化为空
    };
  },
  computed: {
    treeProps() {
      // 可根据需要设置`el-tree`的props属性
      return {
        label: 'label',
        children: 'children'
      };
    }
  },
  mounted() {
    this.expandNodeFromURL(); // 在组件挂载后,根据URL展开节点
  },
  methods: {
    expandNodeFromURL() {
      const urlParams = new URLSearchParams(window.location.search);
      const idParam = urlParams.get('id');
      if (idParam) {
        this.expandNodeById(idParam);
      }
    },
    expandNodeById(targetId) {
      const node = this.findNodeById(this.treeData, targetId);
      if (node) {
        this.expandNodeAndLoadData(node);
      }
    },
    findNodeById(data, targetId) {
      for (let i = 0; i < data.length; i++) {
        const node = data[i];
        if (node.id === targetId) {
          return node;
        }
        if (node.children) {
          const result = this.findNodeById(node.children, targetId);
          if (result) {
            return result;
          }
        }
      }
      return null;
    },
    expandNodeAndLoadData(node) {
      this.$refs.tree.setCurrentKey(node.id); // 设置当前节点为选中状态
      this.$refs.tree.setCurrentNode(node); // 设置当前节点为当前树的活动节点
      this.$nextTick(() => {
        this.$refs.tree.expand(node); // 展开当前节点
        this.lazyLoad(node, () => {}); // 加载节点数据
      });
    },
    lazyLoad(node, resolve) {
      // 在此方法中发送请求获取数据
      const nodeId = node.id;
      // 假设发送请求的方法为fetchData,返回的数据为一个数组
      fetchData(nodeId)
        .then(data => {
          // 将获取的数据添加到节点的children属性中
          node.children = data;
          // 通过resolve方法告知组件数据已加载完毕
          resolve();
        })
        .catch(error => {
          console.error('Error occurred while fetching data:', error);
          // 如果请求失败,也需要通过resolve方法告知组件加载完毕,避免出现无限加载状态
          resolve();
        });
    },
    handleNodeClick(node) {
      this.expandNodeAndLoadData(node);
    }
  }
};
</script>

在上述示例中,我们在mounted生命周期钩子中调用了expandNodeFromURL方法。该方法从URL中获取ID参数,并调用expandNodeById方法展开对应的节点。

expandNodeById方法会根据目标ID递归查找节点,并调用expandNodeAndLoadData方法展开节点并进行懒加载数据。

expandNodeAndLoadData方法首先将当前节点设置为选中状态和活动节点,然后通过$refs.tree.expand方法展开节点。在下一个事件循环周期中,我们调用lazyLoad方法加载节点的数据。

最后,我们在handleNodeClick方法中处理节点的点击事件,同样调用expandNodeAndLoadData方法展开节点并加载数据。

请根据你的实际需求和数据结构进行适当的调整,并确保在Vue应用中正确引入element-ui,并按照其文档提供的方式注册和使用组件。同时,确保在URL中包含正确的ID参数。