有时在一个组件中包含多个插槽出口是很有用的。举例来说,在一个 <BaseLayout> 组件中,有如下模板:
<div class="container"><header><!-- 标题内容放这里 --></header><main><!-- 主要内容放这里 --></main><footer><!-- 底部内容放这里 --></footer>
</div>
对于这种场景,<slot> 元素可以有一个特殊的 attribute name,用来给各个插槽分配唯一的 ID,以确定每一处要渲染的内容:
<div class="container"><header><slot name="header"></slot></header><main><slot></slot></main><footer><slot name="footer"></slot></footer>
</div>
这类带 name 的插槽被称为具名插槽。没有提供 name 的 <slot> 出口会隐式地命名为 default。
在父组件中使用 <BaseLayout> 时,我们需要一种方式将多个插槽内容传入到各自目标插槽的出口。此时就需要用到具名插槽了:
要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:
<BaseLayout><template v-slot:header><!-- header 插槽的内容放这里 --></template>
</BaseLayout>
v-slot 有对应的简写 #,因此 <template v-slot:header> 可以简写为 <template #header>。其意思就是将这部分模板片段传入子组件的 header 插槽中。
下面是向 <BaseLayout> 传递插槽内容的代码,指令均使用的是缩写形式:
<BaseLayout><template #header><h1>Here might be a page title</h1></template><template #default><p>A paragraph for the main content.</p><p>And another one.</p></template><template #footer><p>Here's some contact info</p></template>
</BaseLayout>
当一个组件同时接收默认插槽和具名插槽时,所有位于顶级的非 <template> 节点都被隐式地视为默认插槽的内容。所以上面也可以写成:
<BaseLayout><template #header><h1>Here might be a page title</h1></template><!-- 隐式的默认插槽 --><p>A paragraph for the main content.</p><p>And another one.</p><template #footer><p>Here's some contact info</p></template>
</BaseLayout>
现在 <template> 元素中的所有内容都将被传递到相应的插槽。最终渲染出的 HTML 如下:
<div class="container"><header><h1>Here might be a page title</h1></header><main><p>A paragraph for the main content.</p><p>And another one.</p></main><footer><p>Here's some contact info</p></footer>
</div>