Recursive locally registered components

24 Views Asked by At

I have this structure:

Controller:

<template>
  ...
    <modal-controller
      :entity-name="'foo'"
      @passRef="documentModelModalRef = $event"
    />
</template>
<script>
import ModalController from '@/components/modals/ModalController.vue'
// ...

export default {
  name: 'Foo',
  components: {
    // ...
    ModalController,
  },
...

ModalController.vue:

<template>
  <b-modal
    ref="modalController"
    :title="'custom title'"
    hide-footer
    no-close-on-backdrop
  >
      <form-switcher
        :entity-name="'foo'"
        @changeFormData="onChange($event)"
      />
      ...
      </div>
  </b-modal>
</template>

<script>
import FormSwitcher from '@/components/forms/FormSwitcher.vue'
// ...

export default {
  name: 'ModalController',
  components: {
    FormSwitcher,
    // ...
  },
  props: {
    entityName: {
      required: false,
      type: string,
      default: '',
    },
    // ...
  },

  methods: {
   
    onChange(val) {
      console.log('changes:', val)
    },
  },
}
</script>

FormSwitcher.vue:

<template>
  <div>
    <validation-observer ref="validationRef">
      <Form1
        v-if="entityName === 'foo'"
        @changeFormData="onChange($event)"
      />
      <Form2
        v-else-if="entityName === 'bar'"
        @changeFormData="onChange($event)"
      />
      ...
    </validation-observer>
  </div>
</template>

<script>
import { ValidationObserver } from 'vee-validate'
import Form1 from '@/components/forms/Form1.vue'
import Form2 from '@/components/forms/Form2.vue'

export default {
  name: 'FormSwitcher',
  components: {
    ValidationObserver,
    Form1,
    Form2,
  },
  props: {
    entityName: {
      required: false,
      type: String,
      default: '',
    },
  },
  data() {
    return {
      validationRef: null,
    }
  },
  mounted() {
    this.validationRef = this.$refs.validationRef
  },
  methods: {
    onChange(val) {
      this.$emit('changeFormData', val)
    },
  },
}
</script>

Form1.Vue:

<template>
  <b-container>
    <div>
      <!-- form -->
    </div>

    <modal-controller
      :entity-name="'bar'"
      @passRef="ModalRef = $event"
    />

  </b-container>
</template>

<script>
import ModalController from '@/components/modals/ModalController.vue'
// ...

export default {
  name: 'Form1',
  components: {
    ...
    ModalController,
  },
  ...
}
</script>

I have this error:

"Unknown custom element: <modal-controller> - did you register the component correctly? For recursive components, make sure to provide the "name" option." when I open my modal. 

(Controller => ModalController (this component is correctly registered) => FormSwitcher => Form1 => ModalController (this component is unknown)

How to fix it?

I tried to register ModalController globally in main.js, to set an Id to nested ModalController, to change the name at the component (like this)

<template>
  <b-container>
    <div>
      <!-- form -->
    </div>

    <test
      :entity-name="'bar'"
      @passRef="ModalRef = $event"
    />

  </b-container>
</template>

<script>
import ModalController from '@/components/modals/ModalController.vue'
// ...

export default {
  name: 'Form1',
  components: {
    ...
    test: ModalController,
  },
  ...
}
</script>

SOLVED:

I replaced the <modal-controller> component in Form1.vue with a <component> using the "is" attribute and it works

<template>
    <b-container>
        <div>
            <!-- form -->
        </div>
        
        <component :is="modalComponent" :entity-name="'bar'" @passRef="ModalRef = $event" />
        
    </b-container>
</template>
        
<script>
    // imports...
    import ModalController from '@/components/modals/ModalController.vue'
        
    export default {
        name: 'Form1',
        components: {
            // ...
            ModalController,
        },
        data() {
            return {
                modalComponent: ModalController,
                // ...
            }
        },
        // ...
    }
</script>
0

There are 0 best solutions below