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

如何获取v-for循环中动态分组v-model复选框的选中值

按分组获取商品选项复选框选中值的实现方案

场景与现有代码

商品结构JSON

{
  "id": "1000",
  "name": "黑糖波波奶茶",
  "price": 200,
  "image": "xx.png",
  "description": "...",
  "optionGroups":[
    {
      "optionGroupId": "100",
      "optionGroupName": "Ice Choice | 冰量",
      "optionDtos":[
        {"id":"100","name":"0%"},
        {"id":"101","name":"50%"},
        {"id":"102","name":"100%"},
        {"id":"103","name":"120%"},
        {"id":"104","name":"Hot"}
      ]
    },
    {
      "optionGroupId": "101",
      "optionGroupName": "Sugar Choice | 糖量",
      "optionDtos":[
        {"id":"105","name":"0%"},
        {"id":"106","name":"50%"},
        {"id":"107","name":"100%"},
        {"id":"108","name":"120%"}
      ]
    }
  ]
}

现有页面渲染代码

<form ref="detailForm">
  <div class="content">
    <h1 class="name">{{ get_product(product_id)?.name }}</h1>
    <div class="price">{{ get_product(product_id)?.price }}</div>
    <div v-for="optionGroup in get_product(product_id).optionGroups"
         :key="optionGroup.optionGroupId" 
         class="optionGroup">
      <fieldset :data-id="optionGroup.optionGroupId">
        <legend>Choose {{ optionGroup.optionGroupName }}:</legend>
        <div v-for="option in optionGroup.optionDtos" :key="option.id" class="option_div">
          <input type="checkbox" :data-id="option.id" :id="option.id" :name="option.name"
               v-model="selectedOption" :value="option.id" :checked="option.default" />
          <label :for="option.id">{{ option.name }}</label>
        </div>
      </fieldset>
    </div>
    <div class="buttons">
      <button type="button">Check Out</button>
      <button class="addCart" type="button" @click='addToCart(product_id)'>Add To Cart
        <span>
          <svg class="" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 18 20">
            <path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                  d="M6 15a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm0 0h8m-8 0-1-4m9 4a2 2 0 1 0 0 4 2 2 0 0 0 0-4Zm-9-4h10l2-7H3m2 7L3 4m0 0-.792-3H1" />
          </svg>
        </span>
      </button>
    </div>
    <div class="description"></div>
  </div>
</form>

当前问题

现有data中selectedOption为数组,直接绑定能获取值,但尝试用selectedOption[optionGroup.optionGroupId]按分组绑定失败,需要实现按分组ID存储对应组的选中值。当前data定义:

data(){
  return  {selectedOption:[]}
}

解决方案

1. 修改数据结构为对象

将selectedOption改为对象类型,用分组ID作为键,对应值为该组的选中项数组,这样可以按分组存储选中值:

data(){
  return {
    selectedOption: {}
  }
}

2. 调整复选框的v-model与name属性

修改复选框的v-model绑定路径,同时将同组复选框的name统一设置为分组ID,确保Vue能正确收集同组的选中值:

<div v-for="option in optionGroup.optionDtos" :key="option.id" class="option_div">
  <input type="checkbox" 
         :data-id="option.id" 
         :id="option.id" 
         :name="optionGroup.optionGroupId" <!-- 改为分组ID,同组name保持一致 -->
         v-model="selectedOption[optionGroup.optionGroupId]" <!-- 绑定到对应分组的数组 -->
         :value="option.id" 
         :checked="option.default" />
  <label :for="option.id">{{ option.name }}</label>
</div>

3. 初始化分组选中数组(可选)

为了避免Vue响应式问题,可在组件挂载时初始化每个分组的空数组,若有默认选中项也可一并设置:

mounted() {
  const product = this.get_product(this.product_id)
  if (product?.optionGroups) {
    product.optionGroups.forEach(group => {
      // 用$set确保响应式
      this.$set(this.selectedOption, group.optionGroupId, [])
      // 若存在默认选中项,自动填充
      const defaultOpts = group.optionDtos.filter(opt => opt.default).map(opt => opt.id)
      if (defaultOpts.length) {
        this.selectedOption[group.optionGroupId] = defaultOpts
      }
    })
  }
}

原理说明

原数组类型的selectedOption无法通过字符串类型的分组ID作为索引存储数据(数组索引为数字),改为对象后可直接用分组ID作为键,对应存储该组的选中项数组,配合同组统一的name属性,Vue的v-model能自动完成分组值的收集。


内容的提问来源于stack exchange,提问作者M-shootingstar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 10:13:14