Skip to content
目录

组件插槽

1. 渲染作用域

插槽内容无法访问子组件的数据。Vue 模板中的表达式只能访问其定义时所处的作用域

父组件模板中的表达式只能访问父组件的作用域;子组件模板中的表达式只能访问子组件的作用域。

2. 具名插槽

这类带 name 的插槽被称为具名插槽 (named slots)。没有提供 name 的 <slot> 出口会隐式地命名为“default”

要为具名插槽传入内容,我们需要使用一个含 v-slot 指令的 <template> 元素,并将目标插槽的名字传给该指令:

v-slot 有对应的简写 #,因此 <template v-slot:header> 可以简写为 <template #header>。其意思就是“将这部分模板片段传入子组件的 header 插槽中”。

js
<BaseLayout>
  <template v-slot:header>{/* header 插槽的内容放这里 */}</template>
</BaseLayout>

3. 动态插槽名

html
<base-layout>
  <template v-slot:[dynamicSlotName]> ... </template>
  <!-- 缩写为 -->
  <template #[dynamicSlotName]> ... </template>
</base-layout>

4. 默认作用域插槽

默认插槽: 通过子组件标签上的 v-slot 指令,直接接收到了一个插槽 props 对象:

html
<!-- <MyComponent> 的模板 -->
<div>
  <slot :text="greetingMessage" :count="1"></slot>
</div>
js
<MyComponent v-slot="slotProps">
  {{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
// 可以在 v-slot 中使用解构:
<MyComponent v-slot="{ text, count }">
  {{ text }} {{ count }}
</MyComponent>

5. 具名作用域插槽

vue
<template>
  <MyComponent>
    <template v-slot:header="slotProps">
      {{ slotProps }}
    </template>
  </MyComponent>
  // 缩写
  <MyComponent>
    <template #header="headerProps">
      {{ headerProps }}
    </template>
  </MyComponent>
</template>

注意插槽上的 name 是一个 Vue 特别保留的 attribute,不会作为 props 传递给插槽。因此最终 headerProps 的结果是 { message: 'hello' }

html
<slot name="header" message="hello"></slot>

混用了具名插槽与默认插槽,则需要为默认插槽使用显式的 <template> 标签。

vue
<template>
  <MyComponent>
    <!-- 使用显式的默认插槽 -->
    <template #default="{ message }">
      <p>{{ message }}</p>
    </template>

    <template #footer>
      <p>Here's some contact info</p>
    </template>
  </MyComponent>
</template>