I have the following component with a slot:
<template>
<div>
<h2>{{ someProp }}</h2>
<slot></slot>
</div>
</template>
For some reasons, I have to manually instantiate this component. This is how I am doing it:
const Constr = Vue.extend(MyComponent);
const instance = new Constr({
propsData: { someProp: 'My Heading' }
}).$mount(body);
The problem is: I am not able to create slot contents programmatically. So far, I can create simple string based slot:
const Constr = Vue.extend(MyComponent);
const instance = new Constr({
propsData: { someProp: 'My Heading' }
});
// Creating simple slot
instance.$slots.default = ['Hello'];
instance.$mount(body);
The question is - how can I create $slots
programmatically and pass it to the instance I am creating using new
?
Note: I am not using a full build of Vue.js (runtime only). So I don't have a Vue.js compiler available to compile the template on the fly.
Also note that the fallback text of “Text In Slots Example” is replaced entirely. So in the most basic sense when you want to use slots in VueJS, you add the <slot></slot> tags in the child component where you expect to receive data from outside.
How to use it. Using the slot is very easy, we should just write the <slot> component (which is a reserved word in Vue. js) inside the child component's template, where we want to receive data. A child component uses slot.
Vue slots syntax with v-slot directive With new v-slot directive, we can: – combine html layers: component tag and scope of the slot. – combine the slot and the scoped slot in a single directive.
Details on the activator slotVMenu allows users to specify a slotted template named activator , containing component(s) that activate/open the menu upon certain events (e.g., click ).
I looked into TypeScript definition files of Vue.js
and I found an undocumented function on Vue component instance: $createElement()
. My guess is, it is the same function that is passed to render(createElement)
function of the component. So, I am able to solve it as:
const Constr = Vue.extend(MyComponent);
const instance = new Constr({
propsData: { someProp: 'My Heading' }
});
// Creating simple slot
const node = instance.$createElement('div', ['Hello']);
instance.$slots.default = [node];
instance.$mount(body);
But this is clearly undocumented and hence questionable approach. I will not mark it answered if there is some better approach available.
I think I have finally stumbled on a way to programmatically create a slot element. From what I can tell, the approach does not seem to work for functional components. I am not sure why.
If you are implementing your own render method for a component, you can programmatically create slots that you pass to child elements using the createElement method (or whatever you have aliased it to in the render method), and passing a data hash that includes { slot: NAME_OF_YOUR_SLOT } followed by the array of children within that slot.
For example:
Vue.config.productionTip = false
Vue.config.devtools = false;
Vue.component('parent', {
render (createElement) {
return createElement('child', [
createElement('h1', { slot: 'parent-slot' }, 'Parent-provided Named Slot'),
createElement('h2', { slot: 'default' }, 'Parent-provided Default Slot')
])
}
})
Vue.component('child', {
template: '<div><slot name="parent-slot" /><slot /></div>'
})
new Vue({
el: '#app',
template: '<parent />'
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id='app'>
</div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With