Vue <slot> 元素
示例
使用内置的 <slot>
元素将父组件的内容放置在子组件的 <template>
中。
<template>
<div>
<p>SlotComp.vue</p>
<slot></slot>
</div>
</template>
运行示例 »
请参阅下面的更多示例。
定义和用法
内置的
元素用于放置从父组件接收到的内容。
当调用子组件时,开始标签和结束标签之间提供的内容将最终出现在该子组件内的 <slot>
元素处。
一个组件可以容纳多个 <slot>
,并且可以使用 name
属性来命名插槽。 对于具有不同命名槽的组件,我们可以使用 v-slot
指令将内容发送到特定槽。 (示例 3)
如果父元素未提供任何内容,则 <slot>
元素的开始标签和结束标签之间的内容将用作后备内容。 (示例 5)
可以通过 <slot>
属性向父元素提供信息。 (示例 8)
<slot>
元素只是内容的占位符,<slot>
元素本身不会渲染为 DOM 元素。
Props 选项
Props 选项 | 描述 | |
---|---|---|
[any] | 插槽中定义的属性会创建"作用域插槽",并将此类属性发送到父级。 | 运行示例 » |
name | 命名插槽,以便父级可以使用 v-slot 指令将内容定向到特定插槽。 |
运行示例 » |
更多示例
示例 1
使用槽来包裹较大的动态 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>
运行示例 »
示例 2
使用插槽创建页脚。
App.vue
:
<template>
<h3>Reusable Cards</h3>
<p>我们从 food 数组中创建类似卡片的 div 框。</p>
<p>我们还通过重用相同的组件来创建类似卡片的页脚。</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>
运行示例 »
示例 3
使用槽名称,可以将内容发送到特定槽。
SlotComp.vue
:
<h3>组件</h3>
<div>
<slot name="topSlot"></slot>
</div>
<div>
<slot name="bottomSlot"></slot>
</div>
App.vue
:
<h1>App.vue</h1>
<p>该组件有两个 div 标签,每个标签中有一个插槽。</p>
<slot-comp v-slot:bottomSlot>'Hello!'</slot-comp>
运行示例 »
示例 4
组件中有两个槽,发送到组件的内容将最终位于两个槽中。
App.vue
:
<h1>App.vue</h1>
<p>该组件有两个 div 标签,每个标签中有一个插槽。</p>
<slot-comp>'Hello!'</slot-comp>
SlotComp.vue
:
<h3>组件</h3>
<div>
<slot></slot>
</div>
<div>
<slot></slot>
</div>
运行示例 »
示例 5
在插槽中使用后备内容,以便在父级未提供任何内容时呈现某些内容。
App.vue
:
<template>
<h3>Slots Fallback Content</h3>
<p>未提供内容的组件可以在槽标签中包含后备内容。</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>
运行示例 »
示例 6
没有名称的插槽将是父级内容的默认插槽。
SlotComp.vue
:
<h3>组件</h3>
<div>
<slot></slot>
</div>
<div>
<slot name="bottomSlot"></slot>
</div>
App.vue
:
<h1>App.vue</h1>
<p>该组件有两个 div 标签,每个标签中有一个插槽。</p>
<slot-comp>'Hello!'</slot-comp>
运行示例 »
示例 7
使用 v-slot:default
显式定义一个插槽作为默认插槽。
SlotComp.vue
:
<h3>组件</h3>
<div>
<slot></slot>
</div>
<div>
<slot name="bottomSlot"></slot>
</div>
App.vue
:
<h1>App.vue</h1>
<p>该组件有两个 div 标签,每个标签中有一个插槽。</p>
<slot-comp v-slot:default>'Default slot'</slot-comp>
运行示例 »
示例 8
作用域插槽:使用插槽中的 'foodName' 属性将食物名称传达给父级。
SlotComp.vue
:
<template>
<slot
v-for="x in foods"
:key="x"
:foodName="x"
></slot>
</template>
<script>
export default {
data() {
return {
foods: ['Apple','Pizza','Rice','Fish','Cake']
}
}
}
</script>
App.vue
:
<slot-comp v-slot="food">
<h2>{{ food.foodName }}</h2>
</slot-comp>
运行示例 »
示例 9
作用域插槽:基于包含对象的数组,使用插槽中的 props 将多个内容传达给父级。
SlotComp.vue
:
<template>
<slot
v-for="x in foods"
:key="x.name"
:foodName="x.name"
:foodDesc="x.desc"
:foodUrl="x.url"
></slot>
</template>
<script>
export default {
data() {
return {
foods: [
{ name: 'Apple', desc: 'Apples are a type of fruit that grow on trees.', url: 'img_apple.svg' },
{ name: 'Pizza', desc: 'Pizza has a bread base with tomato sauce, cheese, and toppings on top.', url: 'img_pizza.svg' },
{ name: 'Rice', desc: 'Rice is a type of grain that people like to eat.', url: 'img_rice.svg' },
{ name: 'Fish', desc: 'Fish is an animal that lives in water.', url: 'img_fish.svg' },
{ name: 'Cake', desc: 'Cake is something sweet that tastes good but is not considered healthy.', url: 'img_cake.svg' }
]
}
}
}
</script>
App.vue
:
<slot-comp v-slot="food">
<hr>
<h2>{{ food.foodName }}<img :src=food.foodUrl></h2>
<p>{{ food.foodDesc }}</p>
</slot-comp>
运行示例 »
示例 10
使用命名范围槽将一个文本放入"leftSlot",将另一文本放入"rightSlot"。
SlotComp.vue
:
<template>
<slot
name="leftSlot"
:text="leftText"
></slot>
<slot
name="rightSlot"
:text="rightText"
></slot>
</template>
<script>
export default {
data() {
return {
leftText: 'This text belongs to the LEFT slot.',
rightText: 'This text belongs to the RIGHT slot.'
}
}
}
</script>
App.vue
:
<slot-comp #leftSlot="leftProps">
<div>{{ leftProps.text }}</div>
</slot-comp>
<slot-comp #rightSlot="rightProps">
<div>{{ rightProps.text }}</div>
</slot-comp>
运行示例 »
相关页面
Vue 教程:Vue 插槽
Vue 教程:Vue v-slot
Vue 教程:Vue 作用域插槽
Vue 教程:Vue 组件
Vue 参考:Vue v-slot 指令
Vue 参考:Vue $slots 对象