这里有几个问题。首先,使用单选列表,您需要将 v-model 绑定到一个底层变量,以便 Vue 选择正确的选项,在您的示例中,您将单选按钮绑定到数组索引,但您需要这样做:
<input type="radio" value="1" v-model="selected">
<input type="radio" value="2" v-model="selected">
问题是您已经根据correct 的值为每个单选按钮指定了true 或null 的值,因此您需要将该值设置为唯一的值,例如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/