Я не знаю, знакомы ли вы уже с этой функцией, но проверьте этот код, код из приложения Vue 2, созданного поверх API параметров.
<template> <div class="componentWrapper"> <component :is="componentLoader"> </component> </div> </template> <script> export default { name: 'component-wrapper', props: { componentFile: { type: String, default: () => null } }, computed: { componentLoader () { return () => import('./${this.componentFile}') } } } </script>
Здесь вы можете увидеть использование свойства computed
для предоставления/разрешения динамического значения (пути) в качестве свойства для динамического импорта компонента без его загрузки в процессе рендеринга.
Это была суперская вещь.
Итак, я пытался добиться того же результата, что и с Vue 2, но безрезультатно. Есть несколько способов попробовать это с resolveComponent
и defineAsyncComponent
, но с текущей реализацией механики свойств computed
это уже невозможно. Теперь он создает ссылку на реактивный объект ref
и не может быть динамически разрешен, затем загружается как компонент поверх значения свойства и, наконец, визуализируется Vite. Да, я знаю, это немного сложно. Теперь вам нужно каким-то образом указать предопределенный путь — внутри или снаружи компонента, условно или в виде списка JSON, независимо от того, как вам нужно это сделать. Итак, как это сделать? Построив что-то подобное.
<template> <component :is="componentLoaderInit" /> </template> <script setup lang="ts"> interface DynamicComponent{ title?: string; subtitle?: NullableRecord<string>; file: string | StringConstructor; } interface Props { component: DynamicComponent; } defineOptions({ name: 'DynamicComponentProvider', inheritAttrs: false, }); const props = defineProps<Props>(); const componentLoader: () => ComponentDefinition | null = () => { let component: ComponentDefinition | null = null; switch (props.component.file) { case 'componentName': component = defineAsyncComponent({ loader: () => /* @vite-ignore */ import(`@/components/componentName.vue`), }); break; } return component; }; const componentLoaderInit = computed(() => componentLoader()); </script>
Здесь вы видите довольно быструю нотацию switch/case
, которая обеспечивает выбор пути к компоненту поверх динамического свойства component.file
. Кроме того, вы должны предоставить Vite правильный псевдоним, и если у вас есть проблемы с его распознаванием в IDE, используйте комментарий @vite-ignore
. Вот и все. Теперь вы можете использовать его так.
<component-provider :component="{ file: 'componentName' }" />
Просто, быстро и при этом динамично? Может быть, у вас есть лучшее решение? Подскажите, хотелось бы знать наверняка!
Здоровья, Лукас.