如何在Vue3项目中做命名槽?

ome*_*ega 4 slot vue.js vuejs3 vite

在我的 vue 3 脚本设置组件中,我有这个

<template>
    <table>
        <tbody>
            <template v-for="(row, i) in componentProps.rows">
                <tr v-for="(header, j) in componentProps.headers" :key="i + '-' + j" :data-alternating="i%2===0 ? 'even' : 'odd'">
                    <td class="font-weight-bold text-caption">
                        {{ header.title }}
                    </td>
                    <td>
                        <template #test>
                            
                        </template>
                    </td>
                </tr>
            </template>
        </tbody>
    </table>
</template>

<script setup lang='ts'>
const componentProps = defineProps<{
    headers: TableHeader[];
    rows: {[name:string]:any}[];
}>();
</script>
Run Code Online (Sandbox Code Playgroud)

但我收到这个错误

在此输入图像描述

vite 也抱怨这一点

Codegen node is missing for element/if/for node. Apply appropriate transforms first.
4:00:10 PM [vite] Internal server error: Codegen node is missing for element/if/for node. Apply appropriate transforms first.
  Plugin: vite:vue
Run Code Online (Sandbox Code Playgroud)

我该如何解决这个问题?

And*_*hiu 8

插槽是父组件将内容注入子组件内的一种方式,在子组件模板内的预定位置呈现。


更详细地说:您在(子)组件<slot name="test" /> <template>. 您可以将后备内容放入插槽中。如果父组件没有为槽指定任何内容,则将渲染此后备内容。
示例ComponentA.vue

<template>
  <slot name="test">
    Fallback content
  </slot>
  More child component content
</template>
Run Code Online (Sandbox Code Playgroud)

然后将此组件导入另一个组件并将其用作2

<template>
  Some parent content...
  <component-a>
    <template #test>
      I am injected content
    </template>
  </component-a>
  More parent content...
</template>
Run Code Online (Sandbox Code Playgroud)

这将呈现:

Some parent content...
I am injected content
More child component content
More parent content...
Run Code Online (Sandbox Code Playgroud)

如果没有<template #test>指定(例如:)<component-a />,它将呈现:

Some parent content...
Fallback content
More child component content
More parent content...
Run Code Online (Sandbox Code Playgroud)

因此,在您可以<template #test>在任何地方使用之前,您需要<slot name="test" />在组件内部声明,然后将该组件导入到任何其他组件中,并使用将<template #test>父级定义的内容注入到导入组件的模板中,以替换插槽的后备内容(如果它有)任何)。

槽真正有趣且特别有用的是它们能够向父组件的模板公开作用域,父组件可以通过将槽作用域的逻辑与其自己的逻辑相结合来使用该模板来输出动态内容。在这里
阅读更多相关内容。


1 - 插槽也可以是未命名的。默认(或未命名)插槽 (<slot />) 实际上是命名插槽的特殊情况:在幕后,它们被命名default,并且隐式地获取您在父组件中的子组件标签内放置的所有内容。例如,如果上面的ComponentA.vue的模板如下所示:

Some parent content...
I am injected content
More child component content
More parent content...
Run Code Online (Sandbox Code Playgroud)

当用作

Some parent content...
Fallback content
More child component content
More parent content...
Run Code Online (Sandbox Code Playgroud)

...将呈现:

<template>
  <slot />
  Bla bla...
</template>
Run Code Online (Sandbox Code Playgroud)

这也是完整语法的结果:

<component-a>
  Whatever
</component-a>
Run Code Online (Sandbox Code Playgroud)

2 - 槽可以与 DOM 文本节点和 HTML 元素一起使用,就像普通组件一样。为了简单起见,我选择不在这里使用 HTML 元素。如果您使用上面的确切示例,您将获得在单个文本行中呈现的所有内容,因为所有文本都是 HTML 中的内联内容。