To resolve the error "Non-function value encountered for default slot." in a Vue 3 Composition API component, you can follow these steps:
<template>
, ensure that the default slot's value is indeed a function. For example:<template>
<MyComponent>
{{ slotValue }}
</MyComponent>
</template>
<script>
import { defineComponent } from 'vue';
export default defineComponent({
setup() {
const slotValue = () => {
// Your slot logic here
};
return { slotValue };
},
});
</script>
Make sure that slotValue
is indeed a function in the setup function.
The following might not help the original poster of the question as they seem to have already solved their issue. However, I wanted to share that I encountered the same warning message because I was using a component and instead of having its closing tag just at its end - i.e. <v-select ...misc props...></v-select>
, I decided to align the closing tag with the opening one, i.e.:
<v-select ...misc props...
...and event handlers... >
</v-select>
This creates a text node (and thus content for the default slot) between the >
and the <
.
Changing to either:
<v-select ...misc props...
...and event handlers... ></v-select>
or
<v-select ...misc props...
...and event handlers...
></v-select>
solves the issue, and the warning is not displayed anymore.
The correct solution to hide this warning is to change array children to:
{
default: () => children,
}
For your example, it must be changed to this:
return () =>
h(HelloWorld, {}, {
default: () => [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])],
});
Instead of rendering the child slot directly in the parent component (i.e., passing an array of VNodes as the slots argument directly), wrap it in a function:
// src/components/Composite.js
export default defineComponent({
setup(props, { slots }) {
return () => 👇
h(HelloWorld, {}, () => [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
}
});
Note that the inner h()
calls don't need this function wrapper because they're all rendered together with the default slot by the child component.