admin管理员组文章数量:1310420
I've read about 100 threads about this and still can't quite get it.
I'm trying to parse a string template from a backend API and render it, using custom ponents.
I have aliased esm build in vite.config.js
:
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
vue: 'vue/dist/vue.esm-bundler.js',
},
},
Here is my ponent:
<script>
import { defineAsyncComponent, h } from 'vue';
export default {
ponents: {
PageCalculator: defineAsyncComponent(() => import('@/ponents/PageCalculator.vue')), /* eslint-disable-line */
},
props: {
content: {
type: String,
default: '',
},
},
render() {
const render = {
template: `<div class="content">${this.content}</div>`,
};
return h(render);
},
};
</script>
This gives the error Failed to resolve ponent
.
how can I go about dynamically loading the ponent? I have a large number of ponents that the backend can send back, so I wanted to lazily load them.
Here is how it's used from the outer ponent:
<app-page :title="page.title" container-class="w-full">
<piled-content :content="page.content_html" />
</app-page>
The content of the HTML might look like this (the content
prop):
<p>this is a nice sentence</p>
<page-calculator />
<p>this is a <router-link :to="{name: 'home'}">link</router-link></p>
I've read about 100 threads about this and still can't quite get it.
I'm trying to parse a string template from a backend API and render it, using custom ponents.
I have aliased esm build in vite.config.js
:
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
vue: 'vue/dist/vue.esm-bundler.js',
},
},
Here is my ponent:
<script>
import { defineAsyncComponent, h } from 'vue';
export default {
ponents: {
PageCalculator: defineAsyncComponent(() => import('@/ponents/PageCalculator.vue')), /* eslint-disable-line */
},
props: {
content: {
type: String,
default: '',
},
},
render() {
const render = {
template: `<div class="content">${this.content}</div>`,
};
return h(render);
},
};
</script>
This gives the error Failed to resolve ponent
.
how can I go about dynamically loading the ponent? I have a large number of ponents that the backend can send back, so I wanted to lazily load them.
Here is how it's used from the outer ponent:
<app-page :title="page.title" container-class="w-full">
<piled-content :content="page.content_html" />
</app-page>
The content of the HTML might look like this (the content
prop):
<p>this is a nice sentence</p>
<page-calculator />
<p>this is a <router-link :to="{name: 'home'}">link</router-link></p>
Share
Improve this question
edited Apr 23, 2023 at 21:40
Tallboy
asked Apr 23, 2023 at 21:32
TallboyTallboy
13.5k13 gold badges93 silver badges189 bronze badges
3
-
where are you using
PageCalculator
? – Boussadjra Brahim Commented Apr 23, 2023 at 21:34 - @BoussadjraBrahim i edited my question. its HTML ing in as a prop – Tallboy Commented Apr 23, 2023 at 21:41
-
Have you tried defining the src alias with path?
alias: { '@': path.resolve(__dirname, './src') }
. I haven't seen a configuration like yours before. – Samuel Eiche Commented Apr 24, 2023 at 8:14
2 Answers
Reset to default 9Wow, this was such a painful journey, yet the answer is so simple.
here is how you render vue ponents from the server dynamically, even if they're mixed within html
I'm extremely surprised the answer is not in more places... people had me registering global ponents, using methods that didnt't work. I actually eventually just stumbled across it on my own while trying to piece together tons of different answers.
Here's the final version that:
- piles vue code in realtime from the server
- does so with ponents and methods IN that ponent, without requiring global ponents
<script>
import { h } from 'vue';
import AppAlert from '@/ponents/AppAlert.vue';
export default {
props: {
content: {
type: String,
default: '',
},
},
render() {
const r = {
ponents: {
AppAlert,
},
template: `<div class="content">${this.content || ''}</div>`,
methods: {
hello() {
// method "hello" is also available here
},
},
};
return h(r);
},
};
</script>
If you have tons of ponents in your content you can also make them all async ponents:
ponents: {
AppAlert: defineAsyncComponent(() => import('@/ponents/AppAlert.vue')),
...
You should better use Vue slots
for content instead of props
And you should also not interpolate HTML, since it will not work with ponents.
template: `<div class="content">${this.content}</div>`,
Use Vue Render Functions
instead.
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 = {
ponents: {CompiledContent, PageCalculator }
}
const app = createApp(App)
const vm = app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
<div id="app" v-cloak>
<piled-content><page-calculator></page-calculator></piled-content>
</div>
<script src="https://unpkg./vue@3/dist/vue.global.prod.js"></script>
本文标签: javascriptVue 3 h() with custom componentStack Overflow
版权声明:本文标题:javascript - Vue 3 h() with custom component - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741828858a2399810.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论