“默认槽遇到非功能值。”在 Vue 3 Composition API 组件中

2024-03-08

MCVE

https://github.com/hyperbotauthor/minvue3cliapp https://github.com/hyperbotauthor/minvue3cliapp

MCVE 直播

https://codesandbox.io/s/white-browser-fl7ji https://codesandbox.io/s/white-browser-fl7ji

我有一个 Vue 3 cli-service 应用程序,它使用带有插槽的组合 API 组件。

The HelloWorld组件渲染它接收到的槽div:

// src/components/Helloworld.js
import { defineComponent, h } from "vue";

export default defineComponent({
  setup(props, { slots }) {
    return () => h("div", {}, slots);
  }
});

The Composite组件用途HelloWorld in its setup函数并填充其槽:

// 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>

The Composite组件触发此警告:

Non-function value encountered for default slot. Prefer function slots for better performance. 

当我使用时不会触发相同的警告HelloWorld仅来自模板。

我不明白如果我使用模板或其他组件中的插槽有什么区别。

这个警告有什么意义呢?

有什么办法可以消除这个警告吗?


该警告是关于数组的VNodes 创建于setup()的渲染函数Composite.js.

// src/components/Composite.js
export default defineComponent({
  setup(props, { slots }) {
    return () =>
      h(HelloWorld, {}, [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  }
});

这是低效的,因为子槽被渲染了before the HelloWorld组件甚至可以使用它。子槽本质上是在父槽中渲染,然后传递给子槽。将子槽生成包装在函数中会推迟工作,直到渲染子槽。

我不明白如果我使用模板或其他组件中的插槽有什么区别。

@vue/compiler-sfc编译<template>从 SFC 到渲染函数,其中槽作为函数传递,这避免了您观察到的警告。

Solution

而不是在父插槽中渲染子插槽(即传递数组VNodes as the slots直接参数),将其包装在函数中:

// src/components/Composite.js
export default defineComponent({
  setup(props, { slots }) {
    return () =>          ????
      h(HelloWorld, {}, () => [h("div", {}, ["Div 1"]), h("div", {}, ["Div 2"])]);
  }
});

注意内部h()调用不需要这个函数包装器,因为它们都与默认插槽一起呈现由孩子.

demo https://codesandbox.io/s/adoring-dan-d90xj?file=/src/components/Composite.js

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

“默认槽遇到非功能值。”在 Vue 3 Composition API 组件中 的相关文章

随机推荐