Reputation: 2644
Is it possible to have the default slot not compiled?
Or can I access the innerHTML before it gets compiled?
I would like to use the default slot of a component as a template for another component created on the fly.
It seems impossible, i.e. I have looked a while and didn't find anything about it... But a directive like v-if does prevent the compilation of a content. Where can I access this still uncompiled content?
An example would be as follow:
<my-component>
<ul>
<li v-for="a in b">{{a.text}}</li>
</ul>
</my-component>
I need to get the content, as a string, i.e:
<ul>
<li v-for="a in b">{{a.text}}</li>
</ul>
Before it gets compiled.
I tried to get the default slot content at every step of my component's lifecycle, but I only get it compiled.
EDIT: Ok, I'll try to explain what I really try to achieve:
I have these components which are some kind of content holder (tabs), and I can switch between them. They are part of another component (tabs-container). The thing is that I want to be able to configure and initialize my tabs in many different ways. Example:
<tabs-container :tabs="[
{title: 'Tab 4', content: '<p>Lore ipsum...</p>', url: 'tab4'},
{title: 'Tab 5', content: '<p>Lore ipsum...</p>', url: 'tab5'}
]">
<tab title="Tab 1" url="tab1">
<!-- This is bound to the parent data -->
<ul>
<li v-for="a in b">{{a.text}}</li>
</ul>
</tab>
<tab title="Tab 2" component="my-other-component" :data="myData"/>
<tab title="Tab 3" load="true" url="tab3"/>
</tabs-container>
In fact here I can do almost everything, but the Tab 3, because its content is loaded needs to be mutated, and it is not possible.
So I should take the attributes of this tab before it is mounted, incorporate it to my tabs array, and remove it from the slot.
But if I don't mount the slot then I need to treat all the tabs inside it the same way and include them in my global array of tabs (which I cant do with the tabs component from the slot).
But if I do this, I need to be able to get the innerHTML content of my slot as a string, and use it as the template of dynamic local component - the one created on the fly.
Creating components like this, using a dynamic string as template, works, but my problem is getting this string from my slot.
I hope I made sense :)
EDIT 2:
Another possible solution:
I have a content inside a container with v-if=“test”. If I understood well, if test is false my content will not be compiled. If it becomes true, it will. So while test is false, where can I get the content of my v-if? There must be an internal hidden property where I can access this info.
Does anyone know?
Thanks a lot!
Upvotes: 2
Views: 637
Reputation: 34286
The solution you have in mind (getting the raw uncompiled template of a slot in order to dynamically generate a component at runtime) to your problem is not an ideal solution.
If your component template is precompiled (via vue-loader
, for example) then it is impossible to get the template source as a string because it doesn't exist in the final build – the template gets compiled to a JavaScript render function.
Both your TabsContainer and Tab components are doing too much:
tabs
prop (as data) and/or as <tab>
components rendered directly as slots. The tabs
prop isn't necessary; just render out the data as slots directly in the template using v-for
.component
and data
propsload
prop set to trueYour TabContainer and Tab components should be very simple and "dumb" (not having much logic). If you require logic such as needing to fetch content for some tabs via an API then this should be performed by the parent component, or define a wrapper component to do this.
In fact here I can do almost everything, but the Tab 3, because its content is loaded needs to be mutated, and it is not possible.
This point I'm having the most trouble understanding. Is the content you're fetching a component template (i.e. with {{ }}
markup, for example) or is it plain HTML? If the former, then you'll need to compile it at runtime. In either case it's still possible to render the tab after you have fetched the content, just use v-if
or v-for
to render dynamic tabs as slots of the tab container.
I'm not sure what you mean by "needs to be mutated"; even if some part of the Tab template needs to change in response to mutations of the data/content, this can still be achieved completely by rendering out the Tab as you normally would when rendering any kind of dynamic data.
It's difficult for me to provide a solution that ticks every box; if you can provide a fiddle or codesandbox that would be excellent.
Upvotes: 2