Vue 插槽(Slots)
Slots 是 Vue 中一个强大的功能,它允许更灵活和可重复使用的组件。我们使用 Vue 中的 slots 将内容从父组件发送到子组件的 <template>
中。
Slots
到目前为止,我们只使用了 <template>
中的组件作为自闭标签,如下所示:
App.vue:
<template>
<slot-comp ></slot>
</template>
相反,我们可以使用打开和关闭标记,并在其中放置一些内容,例如文本:
App.vue:
<template>
<slot-comp>Hello World!</slot-comp>
</template>
但收到 'Hello World!' 在组件内部并将其显示在页面上,我们需要在组件内部使用 <slot>
标记。<slot>
标记充当内容的占位符,因此在构建应用程序后,<slot>
将被发送给它的内容所取代。
实例
SlotComp.vue:
<template>
<div>
<p>SlotComp.vue</p>
<slot></slot>
</div>
</template>
像卡片一样的 Slots
Slots(插槽)还可以用来包装较大的动态 html 内容块,以获得类似卡片的外观。
早些时候,我们已经将数据作为 props 发送到组件中创建内容,现在我们可以直接在 <slot>
标记中发送 HTML 内容。
实例
App.vue:
<template>
<h3>Slots in Vue</h3>
<p>We create card-like div boxes from the foods array.</p>
<div id="wrapper">
<slot-comp v-for="x in foods">
<img v-bind:src="x.url">
<h4>{{x.name}}</h4>
<p>{{x.desc}}</p>
</slot-comp>
</div>
</template>
当内容进入 <slot>
所在的组件时,我们在 <slot>
周围使用 <div>
,并在本地设置 <div>
的样式,以在不影响应用程序中其他 div 的情况下,在内容周围创建类似卡片的外观。
SlotComp.vue:
<template>
<div> <!-- This div makes the card-like appearance -->
<slot></slot>
</div>
</template>
<script></script>
<style scoped>
div {
box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2);
border-radius: 10px;
margin: 10px;
}
</style>
在内容周围生成类似卡片的框架的组件可以重复使用以创建不同的元素,但使用相同的类似卡片的框。
在本例中,我们使用与食品相同的组件来创建页脚。
实例
App.vue:
<template>
<h3>Reusable Slot Cards</h3>
<p>We create card-like div boxes from the foods array.</p>
<p>We also create a card-like footer by reusing the same component.</p>
<div id="wrapper">
<slot-comp v-for="x in foods">
<img v-bind:src="x.url">
<h4>{{x.name}}</h4>
</slot-comp>
</div>
<footer>
<slot-comp>
<h4>Footer</h4>
</slot-comp>
</footer>
</template>
后备内容(Fallback Content)
如果创建的组件没有内容,我们在 <slot>
中有后备内容。
实例
此应用程序中的第一个组件没有提供任何内容,因此会呈现后备内容。
App.vue:
<template>
<h3>Slots Fallback Content</h3>
<p>A component without content provided can have fallback content in the slot tag.</p>
<slot-comp>
<!-- Empty -->
</slot-comp>
<slot-comp>
<h4>This content is provided from App.vue</h4>
</slot-comp>
</template>
SlotComp.vue:
<template>
<div>
<slot>
<h4>This is fallback content</h4>
</slot>
</div>
</template>