Vue v-model绑定数组单个索引失效:动态表单行复选框状态异常修复
问题根因
你当前的核心问题是所有行的复选框统一绑定了全局的checked变量,没有和每行独立的状态做关联,导致状态联动异常,同时还有多个不符合Vue数据驱动逻辑的实现问题。
修复方案
1. 模板部分修改
<template> <div> <table> <tr v-for="(item, i) of timesheet.items" :key="i"> <td> <input type="checkbox" v-model="item.checked" :id="'disable' + i" > </td> <td> <select2 :id="'project_id-' + i" :disabled="item.checked" :class="{ 'is-invalid': item.project_id.$error, 'is-valid': item.project_id.$dirty && !item.project_id.$error, }" > <option value="">Select</option> <option v-for="project in projects" :selected="project.id == item.project_id" :key="project.id" :value="project.id">{{ project.name }}</option> </select2> </td> </tr> <tr> <td colspan="3"> <button type="button" class="btn btn-sm btn-primary" @click="addRow" >Add Row </button> </td> </tr> </table> </div> </template>
2. 脚本部分修改
<script> import { required, minLength } from "vuelidate/lib/validators"; export default { data() { return { timesheet: { // 初始行增加checked字段初始化 items: [{ project_id: "", checked: false }] }, } }, validations() { return { timesheet: { items: { required, minLength: minLength(1), $each: { project_id: { required: (value, item) => !item.checked } } } } } }, methods: { addRow(){ this.timesheet.items.push({ project_id: "", checked: false, }) } }, } </script>
关键改动说明
- 把复选框的
v-model从全局checked改为绑定每行的item.checked,实现每行状态独立,解决新增行勾选异常的问题 - 移除了手动操作DOM的
disable方法,改用:disabled="item.checked"动态绑定下拉框禁用状态,符合Vue数据驱动逻辑 - 修复了初始第一行没有初始化
checked字段的问题,保证所有行状态结构一致 - 调整了vuelidate的校验逻辑,基于每行的
checked状态判断是否需要必填校验,实现单行校验独立取消 - 把Add Row按钮移出循环,避免每行都有新增按钮(如果业务需要每行都有可以调整,这里是常规实现)
- 修复了模板中id属性使用
{{}}插值的错误写法,改用:id动态绑定
内容的提问来源于stack exchange,提问作者user16780927
相关产品推荐
相关产品推荐

