いくつかの問題がここにあります。まず、あなたはVueのは、正しいオプションを選択したように、1つの基礎となる変数にv-model
をバインドする必要がラジオリストで、あなたの例では、配列のインデックスにあなたのラジオボタンを結合されていますが、実行する必要があります。
<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: ''
}
}
})
次に、あなたのマークアップは、私はのためにいくつかのプロパティを削除しました(だろう明瞭さ):あなたが行うことができますメインVueのインスタンスで次に
<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>
:
<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/
あなたには2番目の問題があります。ユーザーは正解または正しくない回答を選択できますが、主なVueインスタンスは選択された項目について何も知らないので、$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
で)メソッドをトリガー::それは変更されたとき、私たちselected
値と$emit
イベントを見るためにwatcher
を使用していることを行うことができます
<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
で、その後、あなたがボタンにそれを結合してしまい、あなたのマークアップに条件を追加することができます。
<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/
それはあなたのように、CSSの問題ではありませんあなたがチェックするときにそれが1秒未満で働いているのを見ることができます...しかし、私はVueJsがあなたが何が起こっているかを見る必要があるので、答えをチェックするときに州を変えるためにいくつかのイベントを追加していると確信しています –