Vue循环渲染子组件时如何获取逐索引递增的累计emit传值
问题根源
你当前直接在模板内联写total += $event做累加的写法存在两个核心问题:
- 所有循环项共用同一个
total响应式变量,Vue的视图更新是批量执行的,循环渲染阶段不会每次修改变量都触发重渲染,等所有子组件的emit事件都执行完成后才会统一同步视图,最终只能拿到所有值累加后的总和 - 模板内联表达式本身不适合写修改变量这类带副作用的逻辑,渲染过程中可能被多次调用,很容易出现状态计算不符合预期的问题
实现方案
不要用单个变量存全局累加值,改为维护和循环数组等长的累计值数组,按索引存储每个位置对应的累计结果即可:
- 调整模板绑定,事件处理时传入当前循环索引,判断子组件显示时取当前索引对应的累计值:
<template> <div> <div v-for="data, index in myArr" :key="index"> <child-block-1 :data="data" @emittedData="(val) => handleCumulative(val, index)" /> <child-block-2 v-if="cumulativeArr[index] > 10" /> </div> </div> </template>
- 在脚本中定义累计逻辑,用临时变量按顺序累加,每个索引位的结果存入数组对应位置:
import { ref } from 'vue' const myArr = ref(/* 你的原始数据源 */) // 初始化和数据源等长的累计值数组 const cumulativeArr = ref(myArr.value.map(() => 0)) // 临时运行时累加变量 let tempTotal = 0 const handleCumulative = (emitVal, currentIndex) => { tempTotal += emitVal // 给当前索引位存入到当前位置为止的累计结果 cumulativeArr.value[currentIndex] = tempTotal }
如果你的子组件是挂载完成就自动触发传值、不需要用户交互触发事件,也可以直接在onMounted钩子中按索引顺序遍历数据源,逐次计算累计值存入数组,不需要依赖事件监听做累加。
注意:所有会修改响应式状态的逻辑都尽量写到方法或者生命周期钩子中,不要直接写在模板内联表达式里,避免渲染重复调用导致状态错乱。
内容的提问来源于stack exchange,提问作者Rain Rain
相关产品推荐
相关产品推荐

