插槽内容与出口
父组件为子组件传递一些模板片段,让子组件在它们的组件中渲染这些片段。
示例:
<FancyButton>
Click me! <!-- 插槽内容 -->
</FancyButton>
<!-- <FancyButton> -->
<button class="fancy-btn">
<slot></slot> <!-- 插槽出口 -->
</button>
结果:
<button class="fancy-btn">Click me!</button>
slot 元素是一个插槽出口 (slot outlet),标示了父元素提供的插槽内容 (slot content) 将在哪里被渲染。
插槽内容可以是任意合法的模板内容,除了文本。还可以是多个元素,甚至是组件。
渲染作用域
插槽内容可以访问到父组件的数据作用域,因为插槽内容本身是在父组件模板中定义的。但它无法访问子组件的数据。
默认插槽
子组件仅有一个没有带任何属性的slot标签。
示例:
<button type="submit">
<slot></slot>
</button>
默认内容是指写在 slot 标签之间的内容,当,父组件没有提供内容时,就展示默认内容。
示例:
<button type="submit">
<slot>
Submit <!-- 默认内容 -->
</slot>
</button>
具名插槽
slot 元素通过name属性,来给各个插槽分配唯一的 ID。
示例:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
向具名插槽传入内容,使用含 v-slot 指令的 template 元素,将目标插槽的名字传给该指令。
示例:
<BaseLayout>
<template v-slot:header>
<!-- header 插槽的内容放这里 -->
</template>
</BaseLayout>
v-slot 的简写 #,所以 template v-slot:header 可以简写为 template #header。
条件插槽
根据插槽是否存在来渲染某些内容。使用 $slots 属性与 v-if 来实现。
示例:
<template>
<div class="card">
<div v-if="$slots.header" class="card-header">
<slot name="header" />
</div>
<div v-if="$slots.default" class="card-content">
<slot />
</div>
<div v-if="$slots.footer" class="card-footer">
<slot name="footer" />
</div>
</div>
</template>
动态插槽名
示例:
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
<!-- 缩写为 -->
<template #[dynamicSlotName]>
...
</template>
</base-layout>
作用域插槽
插槽的内容使用子组件域内的数据。我们需要向一个插槽的出口上传递 attributes。
子组件传入插槽的 props 作为了 v-slot 指令的值,可以在插槽内的表达式中访问。
示例:
<!-- <MyComponent> 的模板 -->
<div>
<slot :text="greetingMessage" :count="1"></slot>
</div>
默认作用域插槽
默认插槽接受到插槽 props 对象:v-slot="slotProps"。
示例:
<MyComponent v-slot="slotProps">
{{ slotProps.text }} {{ slotProps.count }}
</MyComponent>
具名作用域插槽
具名插槽接受到插槽 props 对象:v-slot:name="slotProps"。
示例:
<MyComponent>
<template v-slot:header="headerProps">
{{ headerProps }}
</template>
<template v-slot:default="defaultProps">
{{ defaultProps }}
</template>
<template v-slot:footer="footerProps">
{{ footerProps }}
</template>
</MyComponent>
缩写:
<MyComponent>
<template #header="headerProps">
{{ headerProps }}
</template>
<template #default="defaultProps">
{{ defaultProps }}
</template>
<template #footer="footerProps">
{{ footerProps }}
</template>
</MyComponent>