I am creating this wizard with a bunch of steps, but the amount of steps depends on what the user selects in step 1 via checkboxes. Step 1 is fixed so it will always be there and so are the last two steps. Between the first and the second last steps are dynamic steps (lets call them components) I get from an array. So on step 1 if I check task 1's checkbox then a tab will appear with task 1's content, but here is my problem I need the tasks I add to the array to be components and not just strings I get from the value property of the checkbox.
Template:
<template>
<div >
<ul id="stepsList" >
<li>
<div >
<h3>Setup</h3>
</div>
<div >
<label for="projTitle">Give this project a name</label>
<input type="text" placeholder="Title of Project" id="projTitle" />
</div>
<div >
<input type="checkbox" v-model="steps" value="Task1" id="addTask1" />
<label for="addTask1">Task 1</label>
</div>
<div >
<input type="checkbox" v-model="steps" value="Task2" id="addTask2" />
<label for="addTask2">Task 2</label>
</div>
<div >
<input type="checkbox" v-model="steps" value="Task3" id="addTask3" />
<label for="addTask3">Task 3</label>
</div>
<div >
<input
type="checkbox"
v-model="steps"
value="Task 4"
id="addTask4"
/>
<label for="addTask4">Task 4</label>
</div>
</li>
<li v-for="(step, index) in steps" :key="index">
<div >
<h3>{{ step }}</h3>
</div>
</li>
<li>
<div >
<h3>Add Docs</h3>
</div>
</li>
<li>
<div >
<h3>Publish</h3>
</div>
</li>
</ul>
<div >
<button type="button" >Next</button>
</div>
</div>
</template>
and here is the script:
<script>
export default {
data() {
return {
steps: [],
};
},
};
</script>
I need the steps I add dynamically with the check boxes in step 1 to be components. How can I accomplish it please?
CodePudding user response:
To create components dynamically on checkbox selection, You can do that by using :is
attribute. Here is the official documentation
.
<li v-for="(step, index) in steps" :key="index">
<component v-bind:is="step"></component>
</li>
And you can register these components dynamically by putting a watcher on steps
array :
Vue.component('Task1', {
template: '<div>Task 1 component</div>'
})
Live Demo :
new Vue({
el: '#app',
data: {
steps: []
},
watch: {
steps: {
handler() {
this.steps.forEach(step => {
Vue.component(step, {
template: `<div>${step} component</div>`
})
});
}
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<ul id="stepsList" >
<li>
<div >
<h3>Setup</h3>
</div>
<div >
<label for="projTitle">Give this project a name</label>
<input type="text" placeholder="Title of Project" id="projTitle" />
</div>
<div >
<input type="checkbox" v-model="steps" value="Task1" id="addTask1" />
<label for="addTask1">Task 1</label>
</div>
<div >
<input type="checkbox" v-model="steps" value="Task2" id="addTask2" />
<label for="addTask2">Task 2</label>
</div>
<div >
<input type="checkbox" v-model="steps" value="Task3" id="addTask3" />
<label for="addTask3">Task 3</label>
</div>
<div >
<input
type="checkbox"
v-model="steps"
value="Task 4"
id="addTask4"
/>
<label for="addTask4">Task 4</label>
</div>
</li>
<li v-for="(step, index) in steps" :key="index">
<component v-bind:is="step"></component>
</li>
<li>
<div >
<h3>Add Docs</h3>
</div>
</li>
<li>
<div >
<h3>Publish</h3>
</div>
</li>
</ul>
</div>