【问题标题】:Conditional Styling of Radio Buttons not working(VueJs)单选按钮的条件样式不起作用(VueJs)
【发布时间】:2017-12-09 09:45:00
【问题描述】:

我正在尝试制作一个测验应用程序。单击选项时,会立即反馈它是否是正确答案。我正在尝试使用 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

【问题讨论】:

  • 这不是 CSS 问题,因为您在检查时可以看到它的工作时间不到一秒钟......但我确信 VueJs 正在添加一些事件以在您检查答案时更改状态,所以你需要看看发生了什么

标签: css vue.js


【解决方案1】:

这里有几个问题。首先,使用单选列表,您需要将 v-model 绑定到一个底层变量,以便 Vue 选择正确的选项,在您的示例中,您将单选按钮绑定到数组索引,但您需要这样做:

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

问题是您已经根据correct 的值为每个单选按钮指定了truenull 的值,因此您需要将该值设置为唯一的值,例如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;
}

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

<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/

【讨论】:

    猜你喜欢
    • 2017-07-02
    • 2019-10-26
    • 1970-01-01
    • 2020-08-04
    • 1970-01-01
    • 2012-12-11
    • 2012-11-16
    • 2015-09-15
    • 2023-03-26
    相关资源
    最近更新 更多