0👍
Ok. So following the recommendations in comments and answers, I found an article/tutorial regarding dynamic slots, this is something totally new I did not know was possible.
The article is here on dev.to:
Building a Table Component with Dynamic Slot Names in Vue 3
And so this is how the Table component tr v-for element looks like:
<tr v-for="group in tableData">
<td v-for="column in props.columns">
<slot :name="`cell(${column.data})`" :value="group[column.data]" :item="group">
{{ group[column.data] }}
</slot>
</td>
</tr>
And here is an example usage:
<Table :columns="tableColumns" :data="reportList">
<template #cell(fileName)="{ value, item }">
<a href="{{ value }}"> {{ value }}</a>
<my-custom-element>Random content</my-custom-element>
</template>
</Table>
This allows for completely dynamic content to be used in any column I want. The article itself also shows other possible deeper customizations that this approach allows to implement.
1👍
UPDATE
You cannot simply render html in a text string to html using h()
.
The result will be the same as when you just put the text string in Mustaches {{}}
inside the template.
Check the playground.
const { createApp, h } = Vue;
const MyCustomComp = {
props: ['content'],
setup(props) {
return () =>
h('div', null, props.content)
}
}
const App = { components: { MyCustomComp } }
const app = createApp(App)
app.mount('#app')
#app { line-height: 2; }
[v-cloak] { display: none; }
<div id="app" v-cloak>
<my-custom-comp :content="'<h1>Some Content</h1>'"></my-custom-comp>
{{ '<h2>Some Other Content</h2>' }}
<div v-html="'<h3>v-html does not work wuth custom components:</h3><MyCustomComp /><my-custom-comp></my-custom-comp>'"></div>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
You can use v-html
to interpolate the standard HTML, but it will not resolve the custom components. Check the div with v-html
.
I would suggest you to consider using slost for your task. It will be much simpler.
Or think about changing your design. It could possibly be done simpler.
Otherwise you will need to parse yourself dynamic content from the text string and render it with the h()
function, which is really very challenging task.
Check my answers on the thema Vue Render Functions
:
- Adding custom HTML element inside template using functions Vue.js
- Vue2 @click doesn’t work with v-html in another component
- Vue 3: How to use the render function to render different components that themselves render different components with slots, events, etc?
Sure it’s possible and I bet, you don’t really need to use a render() function for your scenario.
Usually, if you have an array with data objects, you can just iterate over this array.
Like this
<tr v-for="row in data">
<td>
This is some random text and:
<my-custom-component>{{row.someData}}</my-custom-component>
</td>
</tr>
If you component is not rendered and you see the component tag in the html, like in your case <mycustomcomponent></mycustomcomponent>
then it wasn’t properly registered or was not found.
Also, Vue normally does not render components, when you pass them in a text string over props or some other way. Check on v-html
directive and security risks caused by using Raw HTML in templates.
So, if you want to render things dynamically, then you will need to use Render Function APIs.
But again, in your case I don’t think it’s necessary.