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

Vue.js中使用v-for渲染的Checkbox互斥选择问题

解决方案

你的问题核心是同一行两个Checkbox需要互斥选择,同时维护temp_doc_file数组存储选中项。原代码直接用v-model绑定数组会因为对象引用问题导致选中状态混乱,且无法自动互斥,下面是两种可行的修改方式:

方式一:单独维护每行选中状态(推荐)

这种方式逻辑清晰,避免对象引用带来的问题,同时轻松实现互斥:

  1. 在组件的data中新增一个对象,用来存储每个文档的选中状态:
data() {
  return {
    PersonalDocument: [], // 你的文档数据数组
    selectedDocs: {}, // 结构:{ [doc_id]: 0/1/null },0代表左侧选中,1代表右侧选中,null代表未选
    temp_doc_file: []
  }
}
  1. 修改模板中的Checkbox,不再直接用v-model,而是通过checked绑定状态,同时监听change事件处理互斥逻辑:
<tbody>
  <tr v-for="(item, index) in PersonalDocument" :key="item.doc_id">
    <th scope="row">{{ index + 1 }}</th>
    <td>{{ item.doc_id }}</td>
    <td>{{ item.doc_name }}</td>
    <td>
      <input
        type="checkbox"
        class="form-check-input"
        :checked="selectedDocs[item.doc_id] === 0"
        @change="handleSelect(item.doc_id, 0)"
      />
    </td>
    <td>
      <input
        type="checkbox"
        class="form-check-input"
        :checked="selectedDocs[item.doc_id] === 1"
        @change="handleSelect(item.doc_id, 1)"
      />
    </td>
    <td></td>
  </tr>
</tbody>
  1. 添加handleSelect方法处理互斥和数组更新:
methods: {
  handleSelect(docId, status) {
    // 如果当前状态已选中,则取消选择
    if (this.selectedDocs[docId] === status) {
      delete this.selectedDocs[docId];
    } else {
      // 设置当前选中状态,自动覆盖同一行的另一选项
      this.selectedDocs[docId] = status;
    }
    // 同步更新temp_doc_file数组
    this.temp_doc_file = Object.entries(this.selectedDocs).map(([id, stat]) => ({
      doc_id: id,
      doc_status: stat
    }));
  }
}

方式二:基于原数组绑定修改(不推荐,存在对象引用隐患)

如果想保留原v-model绑定数组的方式,需要在change事件中手动过滤同一文档的其他选项,但要注意对象引用问题:

  1. 修改模板,给每个Checkbox添加@change事件:
<tbody>
  <tr v-for="(item, index) in PersonalDocument" :key="item.doc_id">
    <th scope="row">{{ index + 1 }}</th>
    <td>{{ item.doc_id }}</td>
    <td>{{ item.doc_name }}</td>
    <td>
      <input
        type="checkbox"
        class="form-check-input"
        v-model="temp_doc_file"
        :value="{ doc_id: item.doc_id, doc_status: 0 }"
        @change="handleItemChange(item.doc_id, 0)"
      />
    </td>
    <td>
      <input
        type="checkbox"
        class="form-check-input"
        v-model="temp_doc_file"
        :value="{ doc_id: item.doc_id, doc_status: 1 }"
        @change="handleItemChange(item.doc_id, 1)"
      />
    </td>
    <td></td>
  </tr>
</tbody>
  1. 添加handleItemChange方法:
methods: {
  handleItemChange(docId, status) {
    // 先移除当前文档的所有选中项
    this.temp_doc_file = this.temp_doc_file.filter(item => item.doc_id !== docId);
    // 检查当前选项是否被勾选(因为v-model已经触发了数组更新,所以需要重新判断)
    const isChecked = this.temp_doc_file.some(item => 
      item.doc_id === docId && item.doc_status === status
    );
    // 如果是勾选状态,重新添加当前项
    if (isChecked) {
      this.temp_doc_file.push({ doc_id: docId, doc_status: status });
    }
  }
}

注意:这种方式中,由于每次循环生成的value对象都是新的引用,v-model可能无法正确识别选中状态,导致Checkbox显示异常,因此更推荐方式一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 21:33:31