Sometime when doing thing is harder in template syntax, you can switch to using render function intead.
For example, we have s Stack
component, it dynamically wrapping child element with a div and some default styling applied.
<!DOCTYPE html>
<html lang="en">
<head>
<style>
.mt-4 {
margin: 10px;
}
</style>
<script src="https://unpkg.com/vue@3.0.11/dist/vue.global.js"></script>
</head>
<body>
<div id="app"></div>
<script>
const {h, createApp} = Vue
const Stack = {
props: {
size: {
type: String,
default: '1',
}
},
render() {
const slot = this.$slots.default
? this.$slots.default()
: [];
return h('div', {class: 'stack'}, slot.map(child => {
return h('div', {class: `mt-${this.$props.size}`}, [child])
}))
}
}
const App = {
components: {
Stack
},
template: `
<Stack size="4">
<div>1</div>
<div>2</div>
<div>3</div>
<Stack size="4">
<div>3.1</div>
<div>3.2</div>
<div>3.3</div>
<Stack size="4">
<div>4.1</div>
<div>4.2</div>
<div>4.3</div>
</Stack>
</Stack>
</Stack>
`
}
const mountedApp = createApp(App).mount('#app')
</script>
</body>
</html>
This is easier to do with render function.