1. 前言

Vue3 在 render() 函数中使用 h() 渲染 vnodes 时出现警告:[Vue warn]: Non-function value encountered for default slot. Prefer function slots for better performance. 之前也遇到过该问题,但一直是一知半解,所以今天重新审视下。

2. 问题说明

要重现上述问题,一个简单的示例如下:

componentA.vue

<template>
    <div class="container">
        <slot></slot>
    </div>
</template>

componentB.vue

<script>
import { h } from "vue";
import componentA from "./componentA.vue";

export default {
    name: "componentB",
    components: { componentA },
    render() {
        return h(componentA, "hello, world");
    }
}
</script>

渲染组件 B 时即出现警告信息。

3. 解决方法

Non-function value encountered for default slot. Prefer function slots for better performance. 直译就是「默认插槽为非函数值。推荐使用函数插槽以获得更佳性能。」

原因就在于:组件 A 中我们使用了默认插槽,当组件 B 渲染时,为 A 插入了默认值 hello, world。解决方法很简单,插槽返回一个函数即可。

修改后代码:

<script>
import { h } from "vue";
import componentA from "./componentA.vue";

export default {
    name: "componentB",
    components: { componentA },
    render() {
        // return h(componentA, "hello, world");
        return h(componentA, () => "hello, world");

        // 或者也可以这样,多个插槽时就要这样写
        // return h(componentA, null, { default: () => "hello, world" });
    }
}
</script>