将 v-for 生成的单选按钮的值设置为 true

Setting a value to true for v-for generated radio buttons

table 的行是使用 v-for 循环遍历 graphicState 中的对象数组生成的。我正在尝试创建一列单选按钮。选中单选按钮时,应将 graphicState[index].selected 设置为 true

这个很有趣,但是我如何使用它设置graphicState[index].selectedtrue

<form>
  <div class="row">
    <div class="col-md-12 " align="center">
      <table class="table-striped" v-on:mouseleave="mouseleave()">
        <thead>
          <tr>
            <th></th>
            <th>Show</th>
            <th>Select</th>
            <th>Shape</th>
          </tr>
        </thead>
        <tbody>
          <tr v-for="(form, index) in graphicState" :key="index">
            <td @click="removeDate(index)"><i class="far fa-trash-alt"></i></td>
            <td>
              <input type="checkbox" v-model="form.show">
            </td>
            <td>
              <input type="radio" name="grp" id="grp" value="true" v-model="form.selected">
            </td>
            <td v-on:click="toggleShape(index)">
              {{ form.shape }}
            </td>
          </tr>
        </tbody>
      </table>
      <div v-for="(form, index) in graphicState " :key="index">
      </div>
    </div>
  </div>
</form>

您可以使用 @change 事件处理程序:

<input type="radio" name="grp" id="grp" value="true" v-model="form.selected" @change="onChange($event, index)">

然后在方法中处理:

methods: {
  onChange (event, index) {
    this.graphicState[index].selected = event.target.value
    this.graphicState = JSON.parse(JSON.stringify(this.graphicState))
  }
}

您已经拥有的代码应该将无线电输入的 graphicState[index].selected 设置为 true,但是输入值(因此 graphicState[index].selectedv-model)永远不会设置为 false,如果允许用户改变主意 select 不同的输入,这是一个问题。发生这种情况是因为无线电输入的 change 事件仅在其 checked 属性 设置为真值(在 selection 上)时触发。

一个解决方案是添加一个 change 事件处理程序,为非 selected 输入清除 .selected 值。

// template
<tr v-for="(form, index) in graphicState">
  <input @change="onRadioChange(index)" ...>
</tr>

// script
onRadioChange(selectedIndex) {
  this.graphicState
    .filter((x,i) => i !== selectedIndex) // get non-selected inputs
    .forEach(x => x.selected = false)
}

但是如果你使用HTMLFormElement的原生提交,还有另外一个问题。在下面的模板中,当 v-model 值为 true 时,Vue 将无线电输入的 checked 属性 设置为 true,这告诉 HTMLFormElement使用此特定输入的值作为组 value...

<input type="radio"
       name="grp"
       v-model="form.selected"
       value="true">

所有单选输入都具有相同的值,因此表单数据的接收者无法判断哪个输入是 selected。要解决此问题,请根据迭代器项为每个输入分配一个唯一值。例如,您可以使用 ID:

<input type="radio"
       name="grp"
       v-model="form.selected"
       value="form.id">

new Vue({
  el: '#app',
  data() {
    return {
      graphicState: [
        {id: 'A', selected: false, show: false},
        {id: 'B', selected: false, show: false},
        {id: 'C', selected: false, show: false},
      ]
    }
  },
  methods: {
    mouseleave() {},
    removeDate() {},
    toggleShape() {},
    onRadioChange(selectedIndex) {
      this.graphicState
        .filter((x,i) => i !== selectedIndex)
        .forEach(x => x.selected = false)
    },
  }
})
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
<script src="https://unpkg.com/vue@2.6.8/dist/vue.min.js"></script>

<div id="app">
  <form method="post" action="//httpbin.org/post">
    <div class="row">
      <div class="col-md-12" align="center">
        <table class="table-striped" v-on:mouseleave="mouseleave()">
          <thead>
            <tr>
              <th></th>
              <th>Show</th>
              <th>Select</th>
              <th>Shape</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(form, index) in graphicState" :key="form.id">
              <td @click="removeDate(index)"><i class="far fa-trash-alt"></i></td>
              <td>
                <input type="checkbox" v-model="form.show">
              </td>
              <td>
                <input type="radio" name="grp" :value="form.id" v-model="form.selected" @change="onRadioChange(index)">
              </td>
              <td v-on:click="toggleShape(index)">
                {{ form.shape }}
              </td>
            </tr>
          </tbody>
        </table>
        
        <pre>{{graphicState}}</pre>
      </div>
    </div>
    <button>Submit</button>
  </form>
</div>