I am currently working on a project where I need to dynamically render components based on the state of an array in the parent component (App.vue). As someone who is new to Vue and not very experienced with programming, I am uncertain if this is the most effective approach for my use case. Any advice on whether or not this is the right way to go about it would be greatly appreciated.
The project involves building a troubleshooter that consists of multiple questions. Each question is represented by a component with data structured similar to this:
data: function() {
return {
id: 2,
question: "Has it worked before?",
answer: undefined,
requires: [
{
id: 1,
answer: "Yes"
}
]
}
}
This specific question should only be displayed if the answer to question 1 was 'Yes'.
My main issue lies in figuring out how to conditionally render these components. Currently, my approach involves emitting an event from the child component when a question is answered, which then triggers an update in the parent component's array containing the status of all answered questions. Subsequently, each component needs to check this array to determine which questions have been answered and if they meet the required conditions to show the question.
So, my question is: How can I access and utilize the parent data to show/hide my components accordingly? And more importantly, is this method recommended or should I consider an alternative strategy?
Below is some sample code for reference:
App.vue
<template>
<div id="app">
<div class="c-troubleshooter">
<one @changeAnswer="updateActiveQuestions"/>
<two @changeAnswer="updateActiveQuestions"/>
</div>
</div>
</template>
<script>
import one from './components/one.vue'
import two from './components/two.vue'
export default {
name: 'app',
components: {
one,
two
},
data: function() {
return {
activeQuestions: []
}
},
methods: {
updateActiveQuestions(event) {
let index = this.activeQuestions.findIndex( ({ id }) => id === event.id );
if ( index === -1 ) {
this.activeQuestions.push(event);
} else {
this.activeQuestions[index] = event;
}
}
}
}
</script>
two.vue
<template>
<div v-if="show">
<h3>{{ question }}</h3>
<div class="c-troubleshooter__section">
<div class="c-troubleshooter__input">
<input type="radio" id="question-2-a" name="question-2" value="yes" v-model="answer">
<label for="question-2-a">Yes</label>
</div>
<div class="c-troubleshooter__input">
<input type="radio" id="question-2-b" name="question-2" value="no" v-model="answer">
<label for="question-2-b">No</label>
</div>
</div>
</div>
</template>
<script>
export default {
data: function() {
return {
id: 2,
question: "Lorem Ipsum?",
answer: undefined,
requires: [
{
id: 1,
answer: "Yes"
}
]
}
},
computed: {
show: function() {
// Check if requirements are met in the parent component and return true
return true;
}
},
watch: {
answer: function() {
this.$emit('changeAnswer', {
id: this.id,
question: this.question,
answer: this.answer
})
}
}
}
</script>