跳到主要内容

Slots

Slot Content and Outlet

The <slot> element is a slot outlet that indicates where the parent-provided slot content should be rendered

Render Scope

Slot content has access to the data scope of the parent component, because it is defined in the parent

Fallback Content

<button type="submit">
<slot>
Submit <!-- fallback content -->
</slot>
</button>

Named Slots

<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
<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>

Conditional Slots

You can use the $slots property in combination with a v-if to achieve this

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

Scoped Slots

there are cases where it could be useful if a slot's content can make use of data from both the parent scope and the child scope. To achieve that, we need a way for the child to pass data to a slot when rendering it

<!-- <MyComponent> template -->
<div>
<slot :text="greetingMessage" :count="1"></slot>
</div>


<MyComponent v-slot="{ text, count }">
{{ text }} {{ count }}
</MyComponent>

Named Scoped Slots

<MyComponent>
<template #header="headerProps">
{{ headerProps }}
</template>

<template #default="defaultProps">
{{ defaultProps }}
</template>

<template #footer="footerProps">
{{ footerProps }}
</template>
</MyComponent>

Fancy List Example

<ul>
<li v-for="item in items">
<slot name="item" v-bind="item"></slot>
</li>
</ul>

Renderless Components

While an interesting pattern, most of what can be achieved with Renderless Components can be achieved in a more efficient fashion with Composition API, without incurring the overhead of extra component nesting

<MouseTracker v-slot="{ x, y }">
Mouse is at: {{ x }}, {{ y }}
</MouseTracker>