Reputation: 7338
How can I render the following template in Vue3 setup()
function using the h()
function?
<label v-for="service in services" :key="service">
<slot name="before" :service="service"></slot>
foobar
<slot name="after" :service="service"></slot>
</label>
Upvotes: 2
Views: 5670
Reputation: 138226
The h()
arguments are:
// @returns {VNode}
h(
// {String | Object | Function } tag
// An HTML tag name, a component or an async component.
// Using function returning null would render a comment.
//
// Required.
'div',
// {Object} props
// An object corresponding to the attributes, props and events
// we would use in a template.
//
// Optional.
{},
// {String | Array | Object} children
// Children VNodes, built using `h()`,
// or using strings to get 'text VNodes' or
// an object with slots.
//
// Optional.
[
'Some text comes first.',
h('h1', 'A headline'),
h(MyComponent, {
someProp: 'foobar'
})
]
)
The component's setup()
arguments are below. setup()
can also return a render function (a function that returns a VNode
from h()
):
setup(
// {Object} Component prop values
props,
// {Object} Contains `attrs`, `emit`, and `slots`
context
)
The context's slots
property contains functions for each given slot. These functions receive arguments that are passed to the slot as props, and each function returns the corresponding slot's VNode
. For example, to get the before
slot's VNode
and pass a slot prop of service
, call context.slots.before({ service: 'myService' })
.
So the equivalent render function of your template would look similar to the following:
import { h } from 'vue'
export default {
props: {
services: {
type: Array,
default: () => [],
},
},
setup({ services }, { slots }) {
return () =>
services.map((service) =>
h( //
'label', //
{ // <label :key="service">
key: service, //
}, //
[
slots.before({ service }), // <slot name="before" :service="service" />
'foobar', // foobar
slots.after({ service }) // <slot name="after" :service="service" />
]
) // </label>
)
},
}
Upvotes: 6