Я прочитал около 100 тем по этому поводу и до сих пор не могу понять.
Я пытаюсь разобрать шаблон строки из внутреннего API и отобразить его с помощью пользовательских компонентов.
У меня есть псевдоним для сборки esm vite.config.js:
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
vue: 'vue/dist/vue.esm-bundler.js',
},
},
Вот мой компонент:
<script>
import { defineAsyncComponent, h } from 'vue';
export default {
components: {
PageCalculator: defineAsyncComponent(() => import('@/components/PageCalculator.vue')), /* eslint-disable-line */
},
props: {
content: {
type: String,
default: '',
},
},
render() {
const render = {
template: `<div class = "content">${this.content}</div>`,
};
return h(render);
},
};
</script>
Это дает ошибку Failed to resolve component.
как я могу динамически загружать компонент? У меня есть большое количество компонентов, которые бэкэнд может отправить обратно, поэтому я хотел лениво их загружать.
Вот как он используется из внешнего компонента:
<app-page :title = "page.title" container-class = "w-full">
<compiled-content :content = "page.content_html" />
</app-page>
Содержимое HTML может выглядеть так (реквизит content):
<p>this is a nice sentence</p>
<page-calculator />
<p>this is a <router-link :to = "{name: 'home'}">link</router-link></p>
@BoussadjraBrahim, я отредактировал свой вопрос. его HTML в качестве опоры
Вы пытались определить псевдоним src с помощью пути ? alias: { '@': path.resolve(__dirname, './src') }. Такой конфигурации как у вас я еще не видел.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Вам лучше использовать слоты Vue для контента вместо props
А еще не стоит интерполировать HTML, так как он не будет работать с компонентами.
template: `<div class = "content">${this.content}</div>`,
Вместо этого используйте Vue Render Functions.
const { createApp, h, defineAsyncComponent } = Vue;
const test = { template: 'Test' }
const PageCalculator =
defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
resolve( { template: 'My PageCalculator' } )
})
})
const CompiledContent = {
template: 'Slot: <slot></slot>'
}
const App = {
components: {CompiledContent, PageCalculator }
}
const app = createApp(App)
const vm = app.mount('#app')#app { line-height: 2; }
[v-cloak] { display: none; }<div id = "app" v-cloak>
<compiled-content><page-calculator></page-calculator></compiled-content>
</div>
<script src = "https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>Эй, спасибо. Как это будет работать с моим полным примером с фактическим текстом? Это будут страницы объемом более 2000 слов с добавлением компонентов vue.
Неважно, что вы положите внутрь слота. Просто создайте свой код вокруг этой концепции или примите ее на основе своего кода.
Вау, это было такое болезненное путешествие, но ответ так прост.
вот как вы динамически визуализируете компоненты vue с сервера, даже если они смешаны в html
Я очень удивлен, что ответ не в большем количестве мест ... люди заставляли меня регистрировать глобальные компоненты, используя методы, которые не работали. На самом деле, в конце концов, я просто наткнулся на него сам, пытаясь собрать воедино множество разных ответов.
Вот окончательная версия, которая:
<script>
import { h } from 'vue';
import AppAlert from '@/components/AppAlert.vue';
export default {
props: {
content: {
type: String,
default: '',
},
},
render() {
const r = {
components: {
AppAlert,
},
template: `<div class = "content">${this.content || ''}</div>`,
methods: {
hello() {
// method "hello" is also available here
},
},
};
return h(r);
},
};
</script>
Если в вашем контенте много компонентов, вы также можете сделать их все асинхронными:
components: {
AppAlert: defineAsyncComponent(() => import('@/components/AppAlert.vue')),
...
где вы используете
PageCalculator?