0

I try to create a highly dynamic wizard as a component in Vue. It contains out of three components: the Wizard component itself, a Step component and a single form "MyForm" component. The form can be in edit mode or in read only mode depending on the current step of the wizard.

After some trial and error I finally managed to create such a component and it works. One problem that I struggled to solve was to pass the information if the form is in edit mode or not from the Step component to the child form component.

MyForm.vue

<template>
  <form>
    <div v-if="inEditMode"><i>Form is in edit mode</i></div>
    <div v-else><i>Form is in read only mode</i></div>
  </form>
</template>

<script>
import Vue from "vue";
export default Vue.extend({
  props: ["inEditMode"]
  // mixins: [wizardStepMixin],
});
</script>

Wizard.vue

<Step> <MyForm/> </Step>

Step.vue

<slot :isInEditMode="true"/>

Passing/setting a prop to a slot like I did above did not work (prop did not change).

My solution to set the prop isInEdit on the MyForm is to call a function prepareSlot in the Step component before mounting and updating the Step.

prepareSlot() {
        this.$slots.default.forEach(element => {
            if (!element.data) return

            element.componentOptions.propsData = {
                ...element.componentOptions.propsData,
                inEditMode: this.stepNr === this.currentStep
            }
        })
    }

You can find the complete project on https://codesandbox.io/embed/mzr10wzk0j.

Is there a better way to archive that? Is it safe to do it that way?

wprogLK
  • 488
  • 5
  • 11
  • Why are even using slots? You have to bind that prop to your component like . – Nikolay Vetrov Feb 06 '19 at 21:13
  • I use slots so that my wizard can be highly dynamic. The wizard should only be responsible for managing the current step and containting all the steps. The steps are responsible for rendering the common part like title, description and step number. The form itself should know if it's in edit mode or not. So in my case your suggestion is not an option because then I would have to have the whole logic in the wizard component and explicitly pass the props to each of my forms for every step. This would make the wizard less easy to use. – wprogLK Feb 07 '19 at 08:03
  • By the way setting the current step and the step number of each step as I did in my example is just for simplyfing the example. In my real wizard component I'm using a render function and setting there the props by iterating over `this.$options._renderChildren`and setting props by `step.componentOptions.propsData` as I do it in the step component. My approch is base on [this stackoverflow article](https://stackoverflow.com/a/42767604/6488880) – wprogLK Feb 07 '19 at 08:06

0 Answers0