In my Vue app, I use a v-data-table
, and the column values are rendered using a render function inside a functional component like so:
render(createElement) {
if (this.$props.format) {
return this.$props.format(this.item, this.index, createElement);
}
return createElement('div', this.getText());
},
and then in my format
function (which is part of an object in a separate file), you can use createElement
to create an hTML element and return it. Here's an example from another part of the app:
format: (template, index, createElement) => {
const captureType = template.captureType === 'passphrase' ? 'voice' : template.captureType;
return createElement('div', captureType);
},
So with all that, I'm trying to do something fairly complex, which is a Vuetify icon with a badge. Here's the code from the Vuetify docs.
<v-badge left>
<template v-slot:badge>
<span>6</span>
</template>
<v-icon
large
color="grey lighten-1"
>
shopping_cart
</v-icon>
</v-badge>
As a starting point, I can create the basic badge HTML just fine
format: (item, index, createElement) => {
const propsObj = {
attrs: {
color: 'blue',
},
props: {
overlap: true,
left: true,
},
slots: {
badge: 'dummy',
},
};
return createElement('v-badge', propsObj, [createElement('v-icon', { attrs: { color: 'success', large: true } }, 'account_circle')]);
},
That gets me almost there, in that it shows my icon, and it's wrapped with the badge
element, although no badge content is displayed:
<span class="v-badge v-badge--left v-badge--overlap">
<i aria ....>account_circle></a>
</span>
My issue is getting the display value to the badge
slot. What am I missing to do that?
With help from a buddy, I got it working. Here's the final code:
format: (item, index, createElement) => {
const propsObj = {
props: {
overlap: true,
left: true,
color: 'success',
},
};
const icon = createElement('v-icon', { props: { color: 'success', large: true } }, 'account_circle');
const span = createElement('span', { slot: 'badge' }, '5');
return createElement('v-badge', propsObj, [span, icon]);
},
The idea is that I break it down into smaller chunks that mimic the structure I'm trying to create. In this case, it's basically a v-badge
that contains two children: the badge
slot and the v-icon
element. I pass the appropriate config options to each child element, and then pass the two rendered elements to createElement
for the parent v-badge
.