Reputation: 126
Vue allows child components to pass data to parent components using scoped slots this way:
//child.vue
<template>
<slot :msg="'pass me up!'">default message</slot>
</template>
//parent.vue
<template>
<Child v-slot="{ msg }">{{ msg }}</Child>
</template>
And astro has its own version which is:
---
//Child.astro
const html = await Astro.slots.render('default', [Astro.props.msg.toUpperCase()]);
---
<Fragment set:html={html} />
---
//Parent.astro
---
<Child>{ msg => <span>{msg}</span> }</Child>
Is there a way to make Astro access vue scoped slots? Like the following? (which does not work btw)
//child.vue
<template>
<slot :msg="'message from vue!'"></slot>
</template>
---
//Parent.astro
---
<Child>
{ t => <span>{t}</span> }
</Child>
Please ignore the fact that the imports and other boilerplate is ignored for these examples
UPDATE
i found a workaround (but naturally, it's not ideal)
//child.vue
<template>
<template v-if="renderer">
<span v-slot="renderer('message from vue!')"></span>
</template>
<template v-else>
<slot v-else :msg="'message from vue!'"></slot>
</template>
</template>
---
//Parent.astro
---
<Child renderer={ (t : string) => `<span>${t}</span>` }></Child>
i wrote this here and not as an answer because i believe there should be a better proper answer, better than mine
Upvotes: 3
Views: 1001
Reputation: 126
Since i could not find any other answer, this is my best try:
//child.vue
<template>
<template v-if="renderer">
<span v-html="renderer('message from vue!')"></span>
</template>
<template v-else>
<slot v-else :msg="'message from vue!'"></slot>
</template>
</template>
---
//Parent.astro
---
<Child renderer={ (t : string) => `<span>${t}</span>` }/>
Upvotes: 3