Reputation: 833
I want to pass slot's content into a wrap components which one of it's prop will accept html string and render it, here's the code
Parent.vue
<Ellipsis style="max-width: 240px"
>Genes that helped people survive during the time of the Black Death are
more likely to be found in people with autoimmune diseases alive today.
Does this tell scientists anything about what surviving the COVID-19
pandemic might mean for the world’s population?
<template #tooltip>
<div style="text-align: center">
<i>Lorem Ipsum</i><br />
Sed ut perspiciatis unde omnis<br />
iste natus error sit voluptatem accusantium doloremque
laudantium,<br />
totam rem aperiam
</div>
</template>
</Ellipsis>
Ellipsis.vue
<template>
<Tooltip
ref="tooltipRef"
:content="tooltipContent"
>
<span
ref="content"
:class="ellipsisClassRef.valueOf()"
:style="ellipsisStyleRef"
@click="handleClickRef"
>
<slot></slot>
</span>
</Tooltip>
</template>
setup(props, { slots }) {
onMounted(() => {
if (slots.default !== undefined) {
tooltipContent.value = slots.default()[0].children;
}
if (slots.tooltip !== undefined) {
// have to get the html content like below
tooltipContent.value = `<div style="color: blue">hello world</div>`;
}
});
}
So the main problem is how to convert the slot's content( html content) I got from parent, and turn it into the string and pass it to the wrap content. When I console.log(slots.tooltip)
, I know I can get the html content like a nested object like following,
0
:
{__v_isVNode: true, __v_skip: true, type: 'div', props: {…}, key: null, …}
length
:
1
[[Prototype]]
:
Array(0)
at
:
ƒ at()
length
:
1
name
:
"at"
arguments
:
(...)
caller
:
(...)
[[Prototype]]
:
ƒ ()
concat
:
ƒ concat()
constructor
:
ƒ Array()
copyWithin
:
ƒ copyWithin(
but there a lot of things to cover if I want to concat them into a string, so I wonder if there's a way to just get the html content as a string or like a helper function to call to get format like <div style="color:blue">Hello world</div>
.
Upvotes: 4
Views: 2209
Reputation: 5183
You can use v-html
directive to return Raw HTML.
<span v-html="rawHtml"></span>
The other option could be Fallback Content in the slot, if the fallback content is static.
<button type="submit">
<slot>
Submit <!-- fallback content -->
</slot>
</button>
But if the slot content is dynamic, then you should better use the Render Functions
h('div', { style: { color: 'blue' }, innerHTML: 'hello world' })
Check my other answer here for details:
Adding custom HTML element inside template using functions Vue.js
const { createApp, h } = Vue;
const myComponent = {
setup(props) {
return () => h('div', { style: { color: 'blue' }, innerHTML: 'hello world' })
}
}
const App = {
components: {
myComponent
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<my-component></my-component><br/>
</div>
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
Upvotes: 1