2017-12-09 27 views
1

私はクイズアプリを作ろうとしています。オプションをクリックすると、正解かどうかのフィードバックが即座に表示されます。私はVueJSでCSSと条件付きクラススタイリングでこれを達成しようとしています。ラジオボタンの条件付きスタイリングが動作しない(VueJs)

しかし、結果は異なります。オプション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

+0

それはあなたのように、CSSの問題ではありませんあなたがチェックするときにそれが1秒未満で働いているのを見ることができます...しかし、私はVueJsがあなたが何が起こっているかを見る必要があるので、答えをチェックするときに州を変えるためにいくつかのイベントを追加していると確信しています –

答えて

0

いくつかの問題がここにあります。まず、あなたは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/

+0

ありがとう。出来た。 –

関連する問題