Vue3 v-for循环子元素点击始终获取首个数据ID的问题
问题原因与解决办法
核心问题
- 重复ID导致事件绑定混乱:所有行的星期复选框
id都是固定值(比如mon、tue),DOM中id必须唯一,点击标签时只会匹配第一个对应id的输入框,所以永远触发第一行的事件。 - v-for的key错误:用了未定义的
strategy作为key,Vue无法正确区分列表项,导致虚拟DOM复用错误,事件绑定错位。 - 复选框绑定逻辑错误:动态设置
value和手动写checked属性,干扰了Vue的双向绑定逻辑。
修复步骤
1. 修正v-for的key
把列表项的key改成每个条目的唯一标识st.id,确保Vue能正确跟踪每个列表项:
<div v-for="(st, index) in mainList" :key="st.id" class="flex flex-row justify-between gap-x-2" >
2. 给复选框和标签设置唯一ID
每个行的星期复选框ID要带上当前条目的id,保证DOM中ID唯一:
<!-- 周一示例 --> <div class="flex items-center"> <input :id="`mon-${st.id}`" v-model="st.weekdays" type="checkbox" value="MON" class="sr_only hidden peer" @click="changeWeekdays($event, st.id)" /> <label :for="`mon-${st.id}`" class="px-2 py-1 w-12 text-sm border text-center rounded-md cursor-pointer focus:outline-none hover:bg-blue-600 peer-checked:bg-blue-900 peer-checked:border-transparent duration-200 ease-in-out" >Mon</label> </div>
其他星期(TUE/WED/THU/FRI)都要做同样修改,把mon换成对应前缀,ID和for都绑定带st.id的动态值。
3. 简化复选框绑定逻辑
去掉动态:value和checked属性,当v-model绑定数组时,Vue会自动根据数组是否包含value值控制复选框状态,选中时自动把value加入数组,取消时移除:
- 固定
value为对应的星期字符串(比如"MON"、"TUE") - 删除
checked="st.weekdays.includes('MON')"和:value="st.weekdays.includes('MON') ? 'MON' : false"
4. 验证changeWeekdays方法
现在点击不同行的星期标签,就能正确拿到对应条目的id,方法内可添加业务逻辑:
methods: { changeWeekdays(e, id) { console.log('当前操作的条目ID:', id); // 这里添加你的业务逻辑,比如更新后端数据等 } }
完整修改后的HTML核心部分示例
<div v-for="(st, index) in mainList" :key="st.id" class="flex flex-row justify-between gap-x-2" > <div>{{ st.id }}</div> <div>{{ st.name }}</div> <div class="flex gap-1"> <!-- 周一 --> <div class="flex items-center"> <input :id="`mon-${st.id}`" v-model="st.weekdays" type="checkbox" value="MON" class="sr_only hidden peer" @click="changeWeekdays($event, st.id)" /> <label :for="`mon-${st.id}`" class="px-2 py-1 w-12 text-sm border text-center rounded-md cursor-pointer focus:outline-none hover:bg-blue-600 peer-checked:bg-blue-900 peer-checked:border-transparent duration-200 ease-in-out" >Mon</label> </div> <!-- 周二 --> <div class="flex items-center"> <input :id="`tue-${st.id}`" v-model="st.weekdays" type="checkbox" value="TUE" class="sr_only hidden peer" @click="changeWeekdays($event, st.id)" /> <label :for="`tue-${st.id}`" class="px-2 py-1 w-12 text-sm border text-center rounded-md cursor-pointer focus:outline-none hover:bg-blue-600 peer-checked:bg-blue-900 peer-checked:border-transparent duration-200 ease-in-out" >Tue</label> </div> <!-- 周三 --> <div class="flex items-center"> <input :id="`wed-${st.id}`" v-model="st.weekdays" type="checkbox" value="WED" class="sr_only hidden peer" @click="changeWeekdays($event, st.id)" /> <label :for="`wed-${st.id}`" class="px-2 py-1 w-12 text-sm border text-center rounded-md cursor-pointer focus:outline-none hover:bg-blue-600 peer-checked:bg-blue-900 peer-checked:border-transparent duration-200 ease-in-out" >Wed</label> </div> <!-- 周四 --> <div class="flex items-center"> <input :id="`thu-${st.id}`" v-model="st.weekdays" type="checkbox" value="THU" class="sr_only hidden peer" @click="changeWeekdays($event, st.id)" /> <label :for="`thu-${st.id}`" class="px-2 py-1 w-12 text-sm border text-center rounded-md cursor-pointer focus:outline-none hover:bg-blue-600 peer-checked:bg-blue-900 peer-checked:border-transparent duration-200 ease-in-out" >Thu</label> </div> <!-- 周五 --> <div class="flex items-center"> <input :id="`fri-${st.id}`" v-model="st.weekdays" type="checkbox" value="FRI" class="sr_only hidden peer" @click="changeWeekdays($event, st.id)" /> <label :for="`fri-${st.id}`" class="px-2 py-1 w-12 text-sm border text-center rounded-md cursor-pointer focus:outline-none hover:bg-blue-600 peer-checked:bg-blue-900 peer-checked:border-transparent duration-200 ease-in-out" >Fri</label> </div> </div> </div>
内容的提问来源于stack exchange,提问作者Adds
相关产品推荐
相关产品推荐

