Vue - 多个无线电输入,检查值? [英] Vue - Multiple radio inputs, checked value?

查看:23
本文介绍了Vue - 多个无线电输入,检查值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在创建一个简单的轮询生成器时正在学习 vue,但我在无线电输入方面遇到了问题.

问题可以有两种类型之一 - select 或 range(两者都是单选输入,select"是单选单选题,range"是单选题,有 1-5 个值,如上所示下图;稍后我必须修复命名...).

问题是,当我在渲染投票时,我有多少个无线电输入组,但选择一个值不会检查无线电输入.

我通过 axios.get 获得了包含问题和可能答案的投票.

模板片段:

 <div class="card mb-2" v-for="question in poll.Questions"><div class="card-header p-2">{{question.question}}</div><div class="card-body pb-1"><div class="form-group" v-if="question.type === 'radio'" ><div v-for="answer in question.QuestionAnswers"><input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)"><label v-bind:for="answer.id">{{answer.answer}}</label>

<div v-else-if="question.type === 'range'"><p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p><div class="form-group d-flex justify-content-center" ><label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers"><input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)"><<;span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>

数据:

data() {返回 {提交: {电子邮件:未定义,年龄:未定义,答案:[]},民意调查:{},加载:假}}

更新答案:

 updateAnswer(question, answer) {让 index = this.submission.answers.findIndex(q => q.questionId === question.id);让答案 = {questionId: question.id,answerId: answer.id};如果(索引=== -1){this.submission.answers.push(ans);} 别的 {this.submission.answers.splice(index, 1);this.submission.answers.push(ans);}console.log(this.submission);}

TL;DR:如何使点击的无线电输入被检查"?

我将数据 POST 到服务器,问题很简单(用户看不到他选择的内容).

根据我的搜索,我得出结论我需要为每个输入设置 v-model,但在这种情况下如何做到这一点?

无线电输入

解决方案

您可以使用 :checked:radio 标记为已选中.

最简单的方法就是为每个答案添加一个 checked 属性并将其绑定到收音机:

基本上对两种问题类型(radiorange)的 input 都做.

并调整您的方法以使其在单击时检查:

updateAnswer(问题,答案){question.QuestionAnswers.forEach(a => Vue.set(a, 'checked', false));answer.checked = true;//不需要调用 Vue.set 因为它现在是响应式的

上述方法取消选中"该问题的所有答案,然后将点击的问题标记为已选中.

完整演示:

new Vue({el: '#app',数据() {返回 {提交: {电子邮件:未定义,年龄:未定义,答案:[]},民意调查:{问题:[{问题:广播问题",id:1,类型:'radio',问题答案:[{id:1,答案:'a'},{id:2,答案:'b'}]},{问题:范围问题",id:2,类型:'范围',问题答案:[{id:1,答案:'a'},{id:2,答案:'b'}]}]},加载:假}},方法: {更新答案(问题,答案){question.QuestionAnswers.forEach(a => Vue.set(a, 'checked', false));answer.checked = true;//不需要调用 Vue.set 因为它现在是响应式的让 index = this.submission.answers.findIndex(q => q.questionId === question.id);让答案 = {questionId: question.id,answerId: answer.id};如果(索引=== -1){this.submission.answers.push(ans);} 别的 {this.submission.answers.splice(index, 1);this.submission.answers.push(ans);}console.log(this.submission);}}})

<script src="https://unpkg.com/vue"></script><div id="应用程序"><label>Ankieta</label><div class="card mb-2" v-for="question in poll.Questions"><div class="card-header p-2">{{question.question}}</div><div class="card-body pb-1"><div class="form-group" v-if="question.type === 'radio'"><div v-for="answer in question.QuestionAnswers"><input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked"><label v-bind:for="answer.id">{{answer.answer}}</label>

<div v-else-if="question.type === 'range'"><p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p><div class="form-group d-flex justify-content-center"><label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers"><input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked"><span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>

I'm learning vue while creating a simple poll generator, but I have an issue with radio inputs.

The question can have one of two types - select or range (both are radio inputs, 'select' is a radio input single-choice question and 'range' is a radio input question with 1-5 values, as shown on the picture below; I'll have to fix the naming later...).

The problem is that while I'm rendering the poll, I have as many radio input groups as there are questions and selecting a value doesn't check the radio input.

I get the poll with questions and possible answers via axios.get.

Template fragment:

  <label>Ankieta</label>
  <div class="card mb-2" v-for="question in poll.Questions">
    <div class="card-header p-2">{{question.question}}</div>
    <div class="card-body pb-1">
      <div class="form-group" v-if="question.type === 'radio'" >
        <div v-for="answer in question.QuestionAnswers">
          <input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)">
          <label v-bind:for="answer.id">{{answer.answer}}</label>
        </div>
      </div>
      <div v-else-if="question.type === 'range'">
        <p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p>
        <div class="form-group d-flex justify-content-center" >
          <label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers">
            <input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)"><span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>
          </label>
        </div>
      </div>
    </div>
  </div>

Data:

data() {
  return {
    submission: {
      email: undefined,
      age: undefined,
      answers: []
    },
    poll: {},
    loading: false
  }
}

updateAnswer:

  updateAnswer(question, answer) {
    let index = this.submission.answers.findIndex(q => q.questionId === question.id);
    let ans = {
      questionId: question.id,
      answerId: answer.id
    };
    if(index === -1) {
      this.submission.answers.push(ans);
    } else {
      this.submission.answers.splice(index, 1);
      this.submission.answers.push(ans);
    }
    console.log(this.submission);
  }

TL;DR: How do I make clicked radio inputs "checked"?

I get the data to POST to the server, the problem is simply aesthetic (the user can't see what he selected).

From what I've searched I concluded I would need to set v-model for each input, but how to do that in this case?

Radio inputs

解决方案

You can use :checked to mark the :radio as checked.

Simplest way is just to add a checked property to each answer and bind it to the radio:

<input type="radio" ... v-bind:checked="answer.checked">

Basically do it for both the inputs of both question types (radio and range).

And adapt your method to make it checked when clicked:

updateAnswer(question, answer) {
  question.QuestionAnswers.forEach(a => Vue.set(a, 'checked', false));
  answer.checked = true; // no need to call Vue.set because it is now reactive

The method above "unchecks" all answers of that question and then marks the clicked question as selected.

Full Demo:

new Vue({
  el: '#app',
  data() {
    return {
      submission: {
        email: undefined,
        age: undefined,
        answers: []
      },
      poll: {Questions: [
        {question: "radio question", id: 1, type: 'radio', QuestionAnswers: [
          {id: 1, answer: 'a'}, {id: 2, answer: 'b'}
        ]},
        {question: "range question", id: 2, type: 'range', QuestionAnswers: [
          {id: 1, answer: 'a'}, {id: 2, answer: 'b'}
        ]}
      ]},
      loading: false
    }
  },
  methods: {
    updateAnswer(question, answer) {
      question.QuestionAnswers.forEach(a => Vue.set(a, 'checked', false));
      answer.checked = true; // no need to call Vue.set because it is now reactive
      let index = this.submission.answers.findIndex(q => q.questionId === question.id);
      let ans = {
        questionId: question.id,
        answerId: answer.id
      };
      if (index === -1) {
        this.submission.answers.push(ans);
      } else {
        this.submission.answers.splice(index, 1);
        this.submission.answers.push(ans);
      }
      console.log(this.submission);
    }
  }
})

<script src="https://unpkg.com/vue"></script>

<div id="app">
  <label>Ankieta</label>
  <div class="card mb-2" v-for="question in poll.Questions">
    <div class="card-header p-2">{{question.question}}</div>
    <div class="card-body pb-1">
      <div class="form-group" v-if="question.type === 'radio'">
        <div v-for="answer in question.QuestionAnswers">
          <input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked">
          <label v-bind:for="answer.id">{{answer.answer}}</label>
        </div>
      </div>
      <div v-else-if="question.type === 'range'">
        <p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p>
        <div class="form-group d-flex justify-content-center">
          <label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers">
            <input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked"><span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>
          </label>
        </div>
      </div>
    </div>
  </div>
</div>

这篇关于Vue - 多个无线电输入,检查值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆