插件窝 干货文章 ElementUI Tree组件点击多次触发接口请求,如何解决?

ElementUI Tree组件点击多次触发接口请求,如何解决?

data 事件 fetchData node 413    来源:    2025-03-23

在使用 ElementUI 的 Tree 组件时,如果点击节点时多次触发接口请求,通常是因为事件处理函数被多次绑定或事件冒泡导致的。以下是一些常见的解决方案:

1. 使用 node-click 事件时避免重复绑定

确保 node-click 事件处理函数不会被多次绑定。如果你在组件的 mountedcreated 钩子中绑定了事件,确保这些钩子不会被多次调用。

<el-tree :data="data" @node-click="handleNodeClick"></el-tree>

methods: {
  handleNodeClick(data, node, component) {
    // 确保这里不会重复触发请求
    if (!this.isLoading) {
      this.isLoading = true;
      this.fetchData(data.id).finally(() => {
        this.isLoading = false;
      });
    }
  },
  fetchData(id) {
    // 发起请求
    return axios.get(`/api/data/${id}`);
  }
}

2. 使用 lazyload 属性

如果你使用的是懒加载模式,确保 load 方法不会被多次调用。可以通过在 load 方法中添加防抖或节流来避免多次触发。

<el-tree :data="data" :load="loadNode" lazy></el-tree>

methods: {
  loadNode(node, resolve) {
    if (node.level === 0) {
      return resolve([{ name: 'region' }]);
    }
    if (node.level > 1) return resolve([]);

    // 防抖处理
    if (!this.isLoading) {
      this.isLoading = true;
      this.fetchData(node.data.id).then(data => {
        resolve(data);
      }).finally(() => {
        this.isLoading = false;
      });
    }
  },
  fetchData(id) {
    // 发起请求
    return axios.get(`/api/data/${id}`);
  }
}

3. 使用 v-once 指令

如果你确定某个节点不需要重新渲染,可以使用 v-once 指令来避免重复渲染和事件绑定。

<el-tree :data="data">
  <template v-slot="{ node }">
    <span v-once>{{ node.label }}</span>
  </template>
</el-tree>

4. 使用 debouncethrottle 函数

如果你需要在事件处理函数中执行异步操作,可以使用 debouncethrottle 函数来限制事件的触发频率。

import { debounce } from 'lodash';

methods: {
  handleNodeClick: debounce(function(data, node, component) {
    this.fetchData(data.id);
  }, 300),
  fetchData(id) {
    // 发起请求
    return axios.get(`/api/data/${id}`);
  }
}

5. 检查事件冒泡

确保事件没有冒泡到父元素或其他元素上,导致事件被多次触发。可以通过 event.stopPropagation() 来阻止事件冒泡。

<el-tree :data="data" @node-click="handleNodeClick"></el-tree>

methods: {
  handleNodeClick(data, node, event) {
    event.stopPropagation();
    this.fetchData(data.id);
  },
  fetchData(id) {
    // 发起请求
    return axios.get(`/api/data/${id}`);
  }
}

6. 使用 key 属性

在某些情况下,重新渲染组件可能会导致事件处理函数被重新绑定。你可以通过给组件添加 key 属性来避免不必要的重新渲染。

<el-tree :data="data" :key="treeKey" @node-click="handleNodeClick"></el-tree>

data() {
  return {
    treeKey: 1
  };
},
methods: {
  handleNodeClick(data, node, component) {
    this.fetchData(data.id);
  },
  fetchData(id) {
    // 发起请求
    return axios.get(`/api/data/${id}`);
  }
}

通过以上方法,你可以有效地避免 ElementUI Tree 组件在点击节点时多次触发接口请求的问题。