Sebas R.
Sebas R.

Reputation: 126

Vue + Astro: Is it posible for astro pages to get data from scoped slots of vue component?

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

Answers (1)

Sebas R.
Sebas R.

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

Related Questions