"Non-function value encountered for default slot." 在 Vue 3 Composition API 组件中
"Non-function value encountered for default slot." in Vue 3 Composition API component
MCVE
https://github.com/hyperbotauthor/minvue3cliapp
MCVE 直播
https://codesandbox.io/s/white-browser-fl7ji
我有一个 Vue 3 cli 服务应用程序,它使用组合 API 带插槽的组件。
HelloWorld
组件呈现它在 div
:
中接收到的插槽
// src/components/Helloworld.js
import { defineComponent, h } from "vue";
export default defineComponent({
setup(props, { slots }) {
return () => h("div", {}, slots);
}
});
Composite
组件在其 setup
函数中使用 HelloWorld
并填充其插槽:
// src/components/Composite.js
import { defineComponent, h } from "vue";
import HelloWorld from "./HelloWorld";
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
}
});
该应用使用两种方式呈现相同的两个 div:
<template>
<!--<img alt="Vue logo" src="./assets/logo.png">-->
Works with plain slots
<HelloWorld>
<div>Div 1</div>
<div>Div 2</div>
</HelloWorld>
Triggers warning when slots are used from other component
<Composite> </Composite>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
import Composite from "./components/Composite";
export default {
name: "App",
components: {
HelloWorld,
Composite,
},
};
</script>
<style>
</style>
Composite
组件触发此警告:
Non-function value encountered for default slot. Prefer function slots for better performance.
当我仅从模板使用 HelloWorld
时,不会触发相同的警告。
我不明白如果我使用来自模板或其他组件的槽有什么区别。
这个警告有什么意义?
有什么方法可以删除此警告?
警告是关于在 Composite.js
的 setup()
渲染函数中创建的 VNode
数组。
// src/components/Composite.js
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
});
这是低效的,因为 在 之前呈现子插槽 HelloWorld
组件甚至可以使用它。子槽本质上是在父槽中渲染,然后传递给子槽。将子槽生成包装在一个函数中可以推迟工作,直到子槽被渲染。
I don't understand what is the difference if I use the slots from a template or from an other component.
@vue/compiler-sfc
将 SFC 中的 <template>
编译成渲染函数,其中插槽作为函数传递,这避免了您观察到的警告。
解决方案
不是在父槽中渲染子槽(即直接将 VNodes
的数组作为 slots
参数传递),而是将其包装在一个函数中:
// src/components/Composite.js
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, () => [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
}
});
请注意,内部 h()
调用不需要此函数包装器,因为它们都与默认插槽 一起由子项呈现。
MCVE
https://github.com/hyperbotauthor/minvue3cliapp
MCVE 直播
https://codesandbox.io/s/white-browser-fl7ji
我有一个 Vue 3 cli 服务应用程序,它使用组合 API 带插槽的组件。
HelloWorld
组件呈现它在 div
:
// src/components/Helloworld.js
import { defineComponent, h } from "vue";
export default defineComponent({
setup(props, { slots }) {
return () => h("div", {}, slots);
}
});
Composite
组件在其 setup
函数中使用 HelloWorld
并填充其插槽:
// src/components/Composite.js
import { defineComponent, h } from "vue";
import HelloWorld from "./HelloWorld";
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
}
});
该应用使用两种方式呈现相同的两个 div:
<template>
<!--<img alt="Vue logo" src="./assets/logo.png">-->
Works with plain slots
<HelloWorld>
<div>Div 1</div>
<div>Div 2</div>
</HelloWorld>
Triggers warning when slots are used from other component
<Composite> </Composite>
</template>
<script>
import HelloWorld from "./components/HelloWorld";
import Composite from "./components/Composite";
export default {
name: "App",
components: {
HelloWorld,
Composite,
},
};
</script>
<style>
</style>
Composite
组件触发此警告:
Non-function value encountered for default slot. Prefer function slots for better performance.
当我仅从模板使用 HelloWorld
时,不会触发相同的警告。
我不明白如果我使用来自模板或其他组件的槽有什么区别。
这个警告有什么意义?
有什么方法可以删除此警告?
警告是关于在 Composite.js
的 setup()
渲染函数中创建的 VNode
数组。
// src/components/Composite.js
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
});
这是低效的,因为 在 之前呈现子插槽 HelloWorld
组件甚至可以使用它。子槽本质上是在父槽中渲染,然后传递给子槽。将子槽生成包装在一个函数中可以推迟工作,直到子槽被渲染。
I don't understand what is the difference if I use the slots from a template or from an other component.
@vue/compiler-sfc
将 SFC 中的 <template>
编译成渲染函数,其中插槽作为函数传递,这避免了您观察到的警告。
解决方案
不是在父槽中渲染子槽(即直接将 VNodes
的数组作为 slots
参数传递),而是将其包装在一个函数中:
// src/components/Composite.js
export default defineComponent({
setup(props, { slots }) {
return () =>
h(HelloWorld, {}, () => [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
}
});
请注意,内部 h()
调用不需要此函数包装器,因为它们都与默认插槽 一起由子项呈现。