// component for one option
const QuestionOption = {
props: ['idx'],
template: `
<div>
<input type="checkbox"
v-model="isCorrect"
@change="setCorrect(isCorrect)"
/>
<label>Option {{ idx + 1 }}:</label>
<input type="text"
v-model="optionText"
@input="setOptionText(optionText)"
/>
</div>
`,
data() {
return {
isCorrect: false,
optionText: ''
}
},
methods: {
setCorrect(e) {
this.$emit('set-correct', {
idx: this.idx,
isCorrect: e
})
},
setOptionText(text) {
this.$emit('set-option-text', {
idx: this.idx,
optionText: text
})
}
}
}
// component for the whole question
const QuestionItem = {
components: {
QuestionOption
},
template: `
<div>
Question:
<input type="text"
v-model="question"
/>
<question-option
v-for="(item, idx) in correctAnswers"
:key="idx"
:idx="idx"
@set-correct="setCorrect"
@set-option-text="setOptionTextAtIdx"
/>
</div>
`,
data() {
return {
question: '',
correctAnswers: [false, false, false, false],
optionTexts: []
}
},
methods: {
setCorrect(e) {
this.correctAnswers[e.idx] = e.isCorrect
this.setQuestionData(this.question, this.correctAnswers, this.optionTexts)
},
setOptionTextAtIdx({
idx,
optionText
}) {
this.optionTexts[idx] = optionText
this.setQuestionData(this.question, this.correctAnswers, this.optionTexts)
},
setQuestionData(question, correctAnswers, optionTexts) {
this.$emit('set-question-data', {
question,
correctAnswers,
optionTexts
})
}
},
watch: {
question: function(val) {
this.setQuestionData(val, this.correctAnswers, this.optionTexts)
}
}
}
// component for previewing the question & correct answers
const Preview = {
props: ['question'],
computed: {
correctAnswerList() {
return this.question.correctAnswers.map((e, idx) => {
return {
isCorrect: e,
text: `Option ${ idx + 1 }`
}
}).filter(({
isCorrect
}) => isCorrect).map(({
text
}) => text).join(', ')
}
},
template: `
<div>
Question: {{ question.question }}<br />
<div
v-for="(option, idx) in question.correctAnswers"
:key="idx + '-' + Date.now()"
>
Option {{ idx + 1 }}: {{ question.optionTexts[idx] }}
</div>
<div>
Correct Answers: {{ correctAnswerList }}
</div>
</div>
`
}
// Vue instance - aggregating the data for the question
new Vue({
el: '#app',
components: {
QuestionItem,
Preview
},
data() {
return {
question: {
question: '',
correctAnswers: [],
optionTexts: []
}
}
},
methods: {
setPreview(questionData) {
this.question = questionData
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<question-item @set-question-data="setPreview"></question-item>
<preview :question="question"></preview>
</div>