0

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 class="stepOne">
    <ul id="stepsList" class="steps">
      <li>
        <div class="stepHeader">
          <h3>Setup</h3>
        </div>
        <div class="projTitle">
          <label for="projTitle">Give this project a name</label>
          <input type="text" placeholder="Title of Project" id="projTitle" />
        </div>
        <div class="stepAdd">
          <input type="checkbox" v-model="steps" value="Task1" id="addTask1" />
          <label for="addTask1">Task 1</label>
        </div>
        <div class="stepAdd">
          <input type="checkbox" v-model="steps" value="Task2" id="addTask2" />
          <label for="addTask2">Task 2</label>
        </div>
        <div class="stepAdd">
          <input type="checkbox" v-model="steps" value="Task3" id="addTask3" />
          <label for="addTask3">Task 3</label>
        </div>
        <div class="stepAdd">
          <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 class="stepHeader">
          <h3>{{ step }}</h3>
        </div>
      </li>
      <li>
        <div class="stepHeader">
          <h3>Add Docs</h3>
        </div>
      </li>
      <li>
        <div class="stepHeader">
          <h3>Publish</h3>
        </div>
      </li>
    </ul>
    <div class="nextPrevBtns">
      <button type="button" class="btn btn-primary">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?

1 Answer 1

1

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" class="steps">
    <li>
      <div class="stepHeader">
        <h3>Setup</h3>
      </div>
      <div class="projTitle">
        <label for="projTitle">Give this project a name</label>
        <input type="text" placeholder="Title of Project" id="projTitle" />
      </div>
      <div class="stepAdd">
        <input type="checkbox" v-model="steps" value="Task1" id="addTask1" />
        <label for="addTask1">Task 1</label>
      </div>
      <div class="stepAdd">
        <input type="checkbox" v-model="steps" value="Task2" id="addTask2" />
        <label for="addTask2">Task 2</label>
      </div>
      <div class="stepAdd">
        <input type="checkbox" v-model="steps" value="Task3" id="addTask3" />
        <label for="addTask3">Task 3</label>
      </div>
      <div class="stepAdd">
        <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 class="stepHeader">
        <h3>Add Docs</h3>
      </div>
    </li>
    <li>
      <div class="stepHeader">
        <h3>Publish</h3>
      </div>
    </li>
  </ul>
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.