I'm trying to build a custom component from a render function.
This component being rendered accepts any number of slots. In the example below there are three available slots (named element_1
, element_2
, element_3
).
The below Array.reduce()
is meant to be equivalent to:
scopedSlots: {
"element_1": () => createElement('div', 'hello world'),
"element_2": () => createElement('div', 'hello world'),
"element_3": () => createElement('div', 'hello world'),
}
This is a slimmed down example with Array.reduce()
:
const records = [
{
"index": 1,
},
{
"index": 2,
},
{
"index": 3,
}
]
render: function (createElement) {
return createElement("replicator-component", {
attrs: { elements: records.length},
scopedSlots: records.reduce((a,x) => ({...a,
['element_' + x.index]:
() => { createElement( 'div', 'hello world') }}), {})
});
},
However nothing renders and there's no errors to guide me. Any ideas?
The difference is that in your reduce
, you are creating the functions as
() => { createElement( 'div', 'hello world') }
while in your hardcoded version (and also in the forEach
loop in @Boussadjra's anwer) they are created as
() => createElement('div', 'hello world')
which actually return
the created element. It's nothing to do with the use of reduce
, which is fine.
const ReplicatorComponent = {
template: `<div>
<h1>replicator-component</h1>
<slot name='element_1'></slot>
<slot name='element_2'></slot>
<slot name='element_3'></slot>
</div>`
};
const records = [
{ "index": 1 },
{ "index": 2 },
{ "index": 3 },
];
Vue.component('my-component', {
render: function(createElement) {
return createElement(ReplicatorComponent, {
attrs: {
elements: records.length
},
scopedSlots: records.reduce((a,x) => ({
...a,
['element_' + x.index]: () =>
createElement( 'div', 'hello world')
}), {})
});
},
});
new Vue({
el: '#app',
data: () => ({})
});
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<div id="app">
<my-component></my-component>
</div>