无线电按钮的条件样式不起作用(VueJs)

时间:2017-12-09 09:45:01

标签: css vue.js

我正在尝试制作一个测验应用。点击选项的地方,立即反馈是否是正确的答案。我试图用VueJS中的CSS和条件类样式来实现这一点。

但结果却不同。让我们说选项1,2和3是错误答案,选项4是正确答案。当我单击选项1或选项2时,选项3将被选中。

.gpquiz .incorrect input[type="radio"]:checked ~ label:before {
    content:'\274C';
    text-indent: .9em;
    color: white;
    background-color: maroon;
}

.gpquiz .incorrect input[type="radio"]:checked ~ label {
    background-color: #fff4f4;

JSFiddle

1 个答案:

答案 0 :(得分:0)

这里有一些问题。首先,使用无线电列表,您需要将v-model绑定到一个基础变量,以便Vue选择正确的选项,在您的示例中,您将单选按钮绑定到数组索引,但您需要执行以下操作:

<input type="radio" value="1" v-model="selected">
<input type="radio" value="2" v-model="selected">

问题是您已根据true值为每个单选按钮指定了值nullcorrect,因此您需要将值设置为唯一值,例如index。另外,因为你要重用这段代码,你应该将它包装在它自己的组件中并将问题作为prop传递给所以:

Vue.component('question', {
  template: '#question',
  props: ['question', 'number'],
  methods: {
    hideOption: function() {
      this.disabled = true;
    }
  },
  data() {
    return {
      selected: ''
    }
  }
})

然后你的标记就是(我为了清楚起见删除了一些属性):

<template id="question">
  <div>
    <h5>{{question.instruction}} {{selected}}</h5>
    <h5>{{number}}. {{question.text}}</h5>
    <ul >
      <li v-for="(option, optionindex) in question.options">
        <div :class="{correct: option['correct'],  incorrect: !option['correct']}">
          <input type="radio" @click="hideOption" :value="optionindex" :name="number" v-model="selected">
          <label>{{option.text}}</label>
        </div>
      </li>
    </ul>
  </div>
</template>

然后在你的主Vue实例中你可以做到:

<div id="app">
  <div class="col-sm-8 gpquiz">
    <question :question="question" :number="index+1" :key="index" v-for="(question, index) in questions"></question>
  </div>
</div>

这是JSFiddle:https://jsfiddle.net/8ocmun6s/

您现在遇到第二个问题,您的用户可以选择正确或错误的答案,但您的主Vue实例并不了解所选内容,为此,我们需要$emit该事件返回到父母,我们可以通过使用watcher来观看我们的selected值,并在事件发生变化时$emit来实现这一点:

  watch: {
    selected(answer) {
      let correct = this.question.options[answer].correct
      // Emit the question number and whether it was correct back to the parent
      this.$emit('user-selected', this.number, correct)
    }
  },

而且,我们现在可以在组件上听取它并触发一个方法(在本例中为selectAnswer):

<question :question="question" :number="index+1" :key="index" @user-selected="selectAnswer" v-for="(question, index) in quiz.questions"></question>

现在我们只需添加该方法:

methods: {
  selectAnswer(number, correct) {
   // use $set here otherwise view won't detect the change
   this.$set(this.userResponses, number-1, correct)
  }
},

现在我们有一系列真假答案,我们可以提供结果,我只想使用computed

computed:{
  correctAnswers(){
    // Return the number of correct answers
    return this.userResponses.filter(x => x).length
  }
},

现在我们可以在用户提交表单时显示和隐藏,因此我们可以将以下内容添加到方法中:

submitAnswers() {
  this.submitted = true;
}

并且还要确保在submitted中声明data,然后您可以将其绑定到按钮并将条件添加到您的标记,最终为:

<div id="app">
  <h1>{{quiz.title}}</h1>
  <hr>
  <div class="col-sm-8 gpquiz" v-if="!submitted">
    <question :question="question" :number="index+1" :key="index" @user-selected="selectAnswer" v-for="(question, index) in quiz.questions"></question>

    <button @click="submitAnswers">
      Submit
    </button>
  </div>
  <h4 v-else>
    You got {{correctAnswers}} out of {{userResponses.length}} Correct!
  </h4>
</div>

这是最终的JSFiddle:https://jsfiddle.net/fvk4L326/