Through my exploration, I discovered that achieving this was not possible by default.
I managed to make it work using custom render functions.
child-slot
component - This component should be placed within the parent slot content in order to format the child component's content. Multiple child-slots
can be added to combine with parent content. It is essential to define a distinct ref
attribute for each one.
use-slot
component - This component is used to specify the content to be passed to the parent as the content of the child-slot
. The content will be enclosed within a span
element.
It requires named
and container
attributes.
named
- Name of the slot where the content will be placed
container
- ref
value of the associated child-slot
use-slot
will automatically locate the first parent slot named according to the specified named
attribute regardless of how deep the child component is nested
child-slot
<script>
export default {
render(createElement) {
return createElement('span', {}, this.content);
},
data() {
return {
nodesToRender: {}
}
},
computed: {
content() {
var result = [];
for (var node in this.nodesToRender) {
result = result.concat(this.nodesToRender[node] || []);
}
return result;
}
}
}
</script>
use-slot
<script>
export default {
abstract: true,
props: {
named: {
type: String,
required: true
},
container: {
type: String,
required: true
}
},
render() {
var parent = this.findParentOfSlot();
var content = this.$slots.default;
var self = this;
this.$parent.$nextTick(function () {
if (parent && parent.$refs && parent.$refs[self.container], parent.$refs[self.container].nodesToRender) {
Vue.set(parent.$refs[self.container].nodesToRender, self.$vnode.tag, content);
}
});
},
methods: {
findParentOfSlot() {
var parent = this.$parent;
while (parent) {
if (parent.$slots && parent.$slots[this.named]) {
return parent.$parent;
}
parent = parent.$parent;
}
return parent;
}
}
}
</script>