Vue – 分页表单中使用多个复选框和单选框时的数值错误。

huangapple go评论55阅读模式
英文:

Vue - Wrong values when using multiple checkboxes and radio in paginated form

问题

I try to make a dynamic form using pagination. On each page there may be a collection of checkboxes or radio buttons. These are the answers options to questions. There may be one or multiple answers for a question, hence the radios and checkboxes. The given answers must be stored as a value to a parameter for each question. Everything seems to work fine as long as I use just radios or just checkboxes. As soon as I mix the two and use the pagination things get messed up. I made a VUE playground to illustrate the problem:

我尝试创建一个使用分页的动态表单。每一页可能有一组复选框或单选按钮。这些是问题的答案选项。每个问题可能有一个或多个答案,因此需要使用单选按钮和复选框。给定的答案必须存储为每个问题的参数值。只要我只使用单选按钮或只使用复选框,一切都运行正常。但一旦混合使用两者并使用分页,问题就会出现混乱。我创建了一个VUE示例来说明这个问题:

Above the inputs you see the result of de checkedNames var. If you move to the third question, you'll see this var also holds the answers to the second question.

在输入框上方,您可以看到checkedNames变量的结果。如果您跳转到第三个问题,您会发现此变量也包含了第二个问题的答案。

I also have an example without the pagination. There everything works as expected:

我还有一个没有分页的示例。在那里,一切都按预期工作:

Does anybody know what's wrong with my script?

有谁知道我的脚本有什么问题吗?

<script>
export default {
  data() {
    return {
      formPosition: 0,
      groups:[{
        title: 'girls',        
        checkedNames: [],
        type: 'checkbox',
        names: ['Mary','Emma','Olivia']
      },
      {
        title: 'boys',
        checkedNames: [],
        type: 'checkbox',
        names: ['Jack','John','Mike']
      },
      {
        title: 'Choose one',
        checkedNames: '',
        type: 'radio',
        names: ['Red','Green','Yellow','Purple']
      }]
    }
  },
  methods: {
    nextStep(){
      setTimeout(() => {
        this.formPosition += 1;
      }, 400);
    },
    prevStep(){

      setTimeout(() => {
        this.formPosition -= 1;
      }, 400);
    }
  }          
}
</script>

<template>

  <div id="'section' + formPosition">
    
    <h4>
      {{ groups[formPosition].title }}
    </h4>
    <div>Checked names: {{ groups[formPosition].checkedNames }}</div>
    
    <ul>
      <li v-for="(name, idx) in groups[formPosition].names" :key="'answer' + idx">
        <input :type="groups[formPosition].type" :id="name" :value="name" :name="'question' + name" v-model="groups[formPosition].checkedNames" />
        <label :for="name">{{ name }}</label>
      </li>
    </ul>
    
    <div class="form-actions">
      <button 
              class="btn btn-primary"
              v-if="formPosition !== 0" 
              @click="prevStep">
        &lsaquo; Previous
      </button>
      <button 
              class="btn btn-primary"
              v-if="formPosition !== groups.length"
              @click="nextStep">
        Next &rsaquo;
      </button>
    </div>
    
  </div>
</template>
英文:

I try to make a dynamic form using pagination. On each page there may be a collection of checkboxes or radio buttons. These are the answers options to questions. There may be one or multiple answers for a question, hence the radios and checkboxes. The given answers must be stored as a value to a parameter for each question. Everything seems to work fine as long as I use just radios or just checkboxes. As soon as I mix the two and use the pagination things get messed up. I made a VUE playground to illustrate the problem:

https://play.vuejs.org/#eNrNVN9r2zAQ/ldufqgT8nPQJ9cJG2UMCt3KNgqj6YNiXxMRWXJl2W0o+d93si3F6ZKxhw1aKNJZ33367vRdXoKPeT6uSgyiIC4SzXMzX0h8zpU2kOIDK4WBl4UESJlhvX6zB9BoSi1dBPCgdHajCm64khFMh+77SqsyL6I7DwQw3AiMIFxxLYpw6D47wMIka0w2mH5hGRYR3N17Msrd5ja1RizVc9g5ki08vGZ6Gw7DT1nGaPkqeMVZeO+AO59yRNJSbUnRP1NyxZINSbhSa0nLNd/gX+q4XCtVICiJp9WE3StbNZqlXB2V8g1TkvBZI1opP1EI9USbm1Lnoquq3e3s0kjM0KxVSiStTjKH+W4w7/W9cLPmxZhJnjH7/DCDsAlwpEoTXjhYgeYHz5C+9chIs/lB5ScpuNwztLiu2WAwg/cesBvC+XTab2PX41xj5SW/CdGjP4iuW+9fXdI2nvjJpMBglgu6pI4A4pRXwNPZIggLTCx7CIODeVwEBN2PWLw+b2Py3ks7oXfdhPtxbUTYtTLiiU+xt80vGyM6d50i6fqVuOKJzT1QUgqvJBYcqhERUCE9Szykop77wOVx8vruRQDRBre2diaLJ9ThwGb5gu3UxFzmpYHIjggBj5dLZ5arbqNltkHFRGkzXGxXe9NjiUXd5kHdADqqRplKUZxi7/aB0BPXA0PiBFuigKipu6GbUz/trm5Zfb5v0kRw9xAT37z9y0AiWFEQkxUwYrUb6Mp9/rI0huy3t2bz59KWRgL9j3JNNtbbRfAaWI34Q0vvvfxuNoMp1fUa+yERPNkQ2o1fRwjAmSjYY6ku4FZpvsJ9hY3E/y+5eaqxQLky69/TvHr3e3eg/laJFcoU4Uw3ZZzQ/9rzLo4nfoqD3S8sXkQM

Above the inputs you see the result of de checkedNames var. If you move to the third question, you'll see this var also holds the answers to the second question.

I also have an example without the pagination. There everything works as expected:

https://play.vuejs.org/#eNqtUsFq3DAQ/ZXBFyXsZn3pybgLJZRCIG3orcQ5aK1JVqwsubLs7LLsv3dGthUXUughYDwa6c3ovTc6Z1/adjP0mBVZ2dVet2FbWTy2zgdQ+Cx7E+BcWQAlg7y6HtcAHkPv7ZwBvHjXt13xmDYAgg4GCxAv2ptOrOftGVCFeo/1AdV32WBXwOPTelF7ark0InbuKBZHdoKLe+lPYi2+No2k8MPoQUvxNAMvqeQdSjt3IkYfxuRO1geicOf2lsK9PuB/8rjdO9chOIv/ZiOWV05svFTavUvlJyqi8M0jMpVfaIx7pcVD71uzZDWtLhzoR1+Zp/FTErBpjQxIGY+M/6XSAww3z85/rrKrOPA1aKvweE1hegFVBoVWBBAd1kE7K2AFVNI8uE5zXmWx5fwOyv2nKSeDzmOTTbQHLpEcQfKEYQrb29GeWXOqWtpGxWXO4L/u6k26qzT6TQt3IilqIWQTu7OaA55YjrTdK3qxYljSwNMqtW37AAWPhoCTAkqSFdyKk0GaniFzzpFb/+6xi1atoiY6Gm4ap9CkdktpdJzPsgJdb+QODRSjlLF+S57wKroQz99050bPZubJjzjeya8yT7PPLn8AHOpAJA==

Doe anybody know what's wrong with my script?

&lt;script&gt;
export default {
data() {
return {
formPosition: 0,
groups:[{
title: &#39;girls&#39;,        
checkedNames: [],
type: &#39;checkbox&#39;,
names: [&#39;Mary&#39;,&#39;Emma&#39;,&#39;Olivia&#39;]
},
{
title: &#39;boys&#39;,
checkedNames: [],
type: &#39;checkbox&#39;,
names: [&#39;Jack&#39;,&#39;John&#39;,&#39;Mike&#39;]
},
{
title: &#39;Choose one&#39;,
checkedNames: &#39;&#39;,
type: &#39;radio&#39;,
names: [&#39;Red&#39;,&#39;Green&#39;,&#39;Yellow&#39;,&#39;Purple&#39;]
}]
}
},
methods: {
nextStep(){
setTimeout(() =&gt; {
this.formPosition += 1;
}, 400);
},
prevStep(){
setTimeout(() =&gt; {
this.formPosition -= 1;
}, 400);
}
}
}
&lt;/script&gt;
&lt;template&gt;
&lt;div id=&quot;&#39;section&#39; + formPosition&quot;&gt;
&lt;h4&gt;
{{ groups[formPosition].title }}
&lt;/h4&gt;
&lt;div&gt;Checked names: {{ groups[formPosition].checkedNames }}&lt;/div&gt;
&lt;ul&gt;
&lt;li v-for=&quot;(name, idx) in groups[formPosition].names&quot; :key=&quot;&#39;answer&#39;+ idx&quot;&gt;
&lt;input :type=&quot;groups[formPosition].type&quot; :id=&quot;name&quot; :value=&quot;name&quot; :name=&quot;&#39;question&#39;+ name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;label :for=&quot;name&quot;&gt;{{ name }}&lt;/label&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;form-actions&quot;&gt;
&lt;button 
class=&quot;btn btn-primary&quot;
v-if=&quot;formPosition !== 0&quot; 
@click=&quot;prevStep&quot;&gt;
&amp;lsaquo; Previous
&lt;/button&gt;
&lt;button 
class=&quot;btn btn-primary&quot;
v-if=&quot;formPosition !== groups.length&quot;
@click=&quot;nextStep&quot;&gt;
Next &amp;rsaquo;
&lt;/button&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/template&gt;

答案1

得分: 1

我意识到收音机元素与复选框元素不同,尽管在代码中只是类型发生了变化。即使外观发生了变化,初始化的元素行为可能没有改变。所以我改变了我的代码的这部分:

从这个:

&lt;li v-for=&quot;(name, idx) in groups[formPosition].names&quot; :key=&quot;&#39;answer&#39;+ idx&quot;&gt;
&lt;input :type=&quot;groups[formPosition].type&quot; :id=&quot;name&quot; :value=&quot;name&quot; :name=&quot;&#39;question&#39;+ name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;label :for=&quot;name&quot;&gt;{{ name }}&lt;/label&gt;
&lt;/li&gt;

改为这个:

&lt;li v-for=&quot;(name, idx) in groups[formPosition].names&quot;&gt;
&lt;input v-if=&quot;groups[formPosition].type === &#39;checkbox&#39;&quot; type=&quot;checkbox&quot; :id=&quot;name&quot; :value=&quot;name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;input v-else type=&quot;radio&quot; :id=&quot;name&quot; :value=&quot;name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;label :for=&quot;name&quot;&gt;{{ name }}&lt;/label&gt;
&lt;/li&gt;

现在它按预期工作。

英文:

I realised the radio element is not the same as a checkbox element even though in code it's just the type that changes. And even though the appearance changed, the initiated element's behaviour did probably not change. So I changed this part of my code:

&lt;li v-for=&quot;(name, idx) in groups[formPosition].names&quot; :key=&quot;&#39;answer&#39;+ idx&quot;&gt;
&lt;input :type=&quot;groups[formPosition].type&quot; :id=&quot;name&quot; :value=&quot;name&quot; :name=&quot;&#39;question&#39;+ name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;label :for=&quot;name&quot;&gt;{{ name }}&lt;/label&gt;
&lt;/li&gt;

to this:

&lt;li v-for=&quot;(name, idx) in groups[formPosition].names&quot;&gt;
&lt;input v-if=&quot;groups[formPosition].type === &#39;checkbox&#39;&quot; type=&quot;checkbox&quot; :id=&quot;name&quot; :value=&quot;name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;input v-else type=&quot;radio&quot; :id=&quot;name&quot; :value=&quot;name&quot; v-model=&quot;groups[formPosition].checkedNames&quot; /&gt;
&lt;label :for=&quot;name&quot;&gt;{{ name }}&lt;/label&gt;
&lt;/li&gt;

And now it's working as expected

答案2

得分: 1

这是要翻译的内容:

"It's a problem with reactivity and the inputs and their bound v-model not updating properly. Since every page has a unique formPosition, adding that as a key to the component root div should help Vue's reactivity system understand when to update. Keeping all your same code, change just the first div:

<div id="'section' + formPosition" :key="formPosition">
```"

<details>
<summary>英文:</summary>

It&#39;s a problem with reactivity and the inputs and their bound v-model not updating properly.  Since every page has a unique `formPosition`, adding that as a `key` to the component root div should help Vue&#39;s reactivity system understand when to update.  Keeping all your same code, change just the first div:

```html
&lt;div id=&quot;&#39;section&#39; + formPosition&quot; :key=&quot;formPosition&quot;&gt;

huangapple
  • 本文由 发表于 2023年5月22日 21:02:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76306482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定