[Vuejs]-Vue 3 – use props string to load component

1👍

There are different ways to solve that. I think in your case it would make sense to use slots. But if you want to keep your approach you can globally define your components in your Vue app.

without slots

const app = createApp({});

// define components globally as async components:
app.component('first-component', defineAsyncComponent(async () => import('path/to/your/FirstComponent.vue'));
app.component('second-component', defineAsyncComponent(async () => import('path/to/your/SecondComponent.vue'));

app.mount('#app');

Then you can use strings and fix some bugs in your component:

  • Don’t use ids, instead use a template ref to access the dialog element
  • Use const instead of let for non-changing values.
  • props are already reactive so you can use the props also directly inside your template and they will be updated automatically when changed from the outside.
// inside <script setup>

import {computed, onMounted, ref, watch} from "vue";
import {useDialogStore} from "@/store/dialog";
import TableSwitcher from "@/components/Dialogs/Components/TableSwitcher.vue"

// use const instead of let, as the values are not changing:
const emit = defineEmits(['confirmDialogConfirmed', 'confirmDialogClose'])

const props = defineProps({
  open: {
    type: Boolean,
    required: true
  },
  id: {
    type: String,
    default: 'main-dialog'
  },
  component: {
    type: String,
    required: true,
  }
});

const dialogStore = useDialogStore()
const question = computed(() => dialogStore.dialogQuestion);
const dialog = ref(null);

watchPostEffect(
  () => {
    if(props.open) {
      dialog.value?.showModal()
    }
  },
  // call watcher also on first lifecycle:
  { immediate: true }
);

let closeDialog = (confirmAction = false) => {
  dialog.value?.close()
  dialogStore.close(confirmAction)
}

<!-- the sfc template -->
<dialog ref="dialog">
  <component :is="props.component" />
</dialog>

with slots

<!-- use your main-dialog -->
<main-dialog :open="open">
  <first-component v-if="condition"/>
  <second-component v-else />
</main-dialog>
<!-- template of MainDialog.vue -->
<dialog ref="dialog">
  <slot />
</dialog>

Leave a comment