vue-quiz の Tips
vue-quiz を作った際にでてきたTipsをまとめておきます
同じID(値)を持った配列をまとめたい
今回の場合、ラジオボタン式(単一解答)なら問題ないけど、チェックボックス式(複数解答)のときに整形する必要がでてきた
つまり
array = [ { id: "1", answer: "d" }, { id: "3", answer: "a" }, { id: "3", answer: "b" }, { id: "3", answer: "c" }, { id: "4", answer: "b" } ]
を↓のようにしたい
formatArray = [ { id: "1", answer: ["d"] }, { id: "3", answer: ["a","b","c"] } { id: "4", answer: ["b"] } ]
こういうときに reduce()
を使うみたい
const data = array.reduce((acc, value) => { acc[value.id] = acc[value.id] ? acc[value.id] : []; acc[value.id] ? acc[value.id].push(value.answer) : [value.answer]; return acc; }, {}); let formattedAnswerArray = Object.entries(data).map(d => ({ id: d[0], answer: d[1] }) );
参考: https://stackoverflow.com/questions/31688459/group-array-items-using-object
配列の比較
これも参考のとおりなのですが、配列を比較、今回の場合は答え合わせの際に、問題の正解とユーザーの解答を比べるときに使いました。
function array_equal(a, b) { if (!Array.isArray(a)) return false; if (!Array.isArray(b)) return false; if (a.length != b.length) return false; for (var i = 0, n = a.length; i < n; ++i) { if (a[i] !== b[i]) return false; } return true; }
というfunctionを作って computed
で
// スコアの計算 calcScore: function () { const correctAnswer = this.correctAnswerArray; // 問題の正解 const userAnswer = this.userAnswerArray; // ユーザーの解答 let userScore = 0; correctAnswer.forEach((value,index) => { const correctAnswerValue = value; const userAnswerValue = userAnswer[index]; // ユーザーの解答が問題の正解とイコールならスコアを+1する if ( array_equal(correctAnswerValue,userAnswerValue) ) { userScore ++; } }); return userScore; }
<template> ... <p>{{calcScore}}問正解です</p> ... </template>
参考: https://marycore.jp/prog/js/array-equal/
<template>
を使って条件分岐
直接HTMLタグに分岐を書かずに <template>
に分岐を書く。
あらかじめどちらに統一すると決めてマークアップしていったほうがいいですね。
answerCorrect()
メソッドで分岐する場合
<div> <template v-if="answerCorrect(hoge,fuga)"> <p class="text text--correct">{{ value }}</p> </template> <template v-else> <p class="text">{{ value }}</p> </template> </div>
カスタムデータ属性(data-*
)をバインドする
<input type="checkbox" v-bind:data-hoge="post.id" >