我正在尝试制作一个测验应用。点击选项的地方,立即反馈是否是正确的答案。我试图用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;
答案 0 :(得分:0)
这里有一些问题。首先,使用无线电列表,您需要将v-model
绑定到一个基础变量,以便Vue选择正确的选项,在您的示例中,您将单选按钮绑定到数组索引,但您需要执行以下操作:
<input type="radio" value="1" v-model="selected">
<input type="radio" value="2" v-model="selected">
问题是您已根据true
值为每个单选按钮指定了值null
或correct
,因此您需要将值设置为唯一值,例如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/