You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue中如何编程统计触发component-loaded事件的子组件数量

解决方案

方案1:集中维护待加载组件清单(兼容性最好,不易出错)

把所有需要监听component-loaded事件的组件统一存为常量数组,新增组件时仅需修改该数组即可,无需调整Watcher里的判断逻辑,还能避免硬编码数值的问题。

代码实现

script部分:

// 统一维护需要监听加载事件的组件列表,新增组件仅需修改此处
const COMPONENTS_TO_LOAD = ['warehouses-01', 'warehouses-03', 'warehouses-04', 'warehouses-07']

export default {
  watch: {
    componentsLoaded() {
      // 直接取数组长度,无需硬编码数值
      if (this.componentsLoaded.size === COMPONENTS_TO_LOAD.length) {
        this.isLoaded = true
      }
    }
  },
  data() {
    return {
      // 用Set存储避免同一组件重复触发事件导致计数错误
      componentsLoaded: new Set(),
      isLoaded: false
    }
  },
  methods: {
    handleComponentLoaded(componentName) {
      this.componentsLoaded.add(componentName)
    }
  }
}

模板部分可以优化为动态渲染,无需重复写组件绑定逻辑:

<template>
  <component
    v-for="compName in COMPONENTS_TO_LOAD"
    :key="compName"
    :is="compName"
    @component-loaded="() => handleComponentLoaded(compName)"
  />
</template>

如果不想用动态组件,继续手写组件标签也可以,只要确保新增的组件名加入COMPONENTS_TO_LOAD数组即可,Watcher逻辑完全不需要修改。

方案2:自动统计子组件数量(无需手动维护清单)

如果不想手动维护组件列表,可以通过子组件标记自动统计总数:

  • Vue2项目可以直接使用$children遍历统计
  • Vue3项目可以给所有目标子组件套一个父容器,通过ref获取容器后统计子组件数量

代码示例(Vue2)

export default {
  data() {
    return {
      componentsLoaded: [],
      isLoaded: false,
      totalLoadComponents: 0
    }
  },
  mounted() {
    // 统计所有带hasLoadEvent自定义属性的子组件
    this.totalLoadComponents = this.$children.filter(child => child.$attrs.hasLoadEvent).length
  },
  watch: {
    componentsLoaded() {
      if (this.componentsLoaded.length === this.totalLoadComponents) {
        this.isLoaded = true
      }
    }
  }
}

模板中给需要统计的子组件加标记即可:

<warehouses-01 hasLoadEvent @component-loaded="() => this.componentsLoaded.push('warehouses-01')" />

方案3:provide/inject主动上报(适合组件嵌套深的场景)

如果子组件嵌套层级较多,可以通过依赖注入的方式实现自动统计,完全不需要手动维护任何列表:

父组件代码

export default {
  provide() {
    return {
      registerLoadComponent: this.registerLoadComponent,
      reportComponentLoaded: this.reportComponentLoaded
    }
  },
  data() {
    return {
      totalLoadComponents: 0,
      loadedComponents: new Set(),
      isLoaded: false
    }
  },
  methods: {
    // 子组件注册上报,统计总数
    registerLoadComponent() {
      this.totalLoadComponents++
    },
    // 子组件加载完成后上报
    reportComponentLoaded(compId) {
      this.loadedComponents.add(compId)
      if (this.loadedComponents.size === this.totalLoadComponents) {
        this.isLoaded = true
      }
    }
  }
}

子组件代码

export default {
  inject: ['registerLoadComponent', 'reportComponentLoaded'],
  mounted() {
    // 注册当前组件为需要统计加载状态的组件
    this.registerLoadComponent()
    // 自身加载逻辑执行完成后上报
    this.reportComponentLoaded(this._uid)
  }
}

该方案新增组件时不需要修改父组件任何代码,只要子组件按规则调用注入的两个方法即可。


内容的提问来源于stack exchange,提问作者knot22

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:36:05