Vue <slot> 元素


示例

使用内置的<slot>元素将父组件中的内容放置在<template>子组件的。

<template>
  <div>  
    <p>SlotComp.vue</p>
    <slot></slot>
  </div>
</template>
运行示例 »

请参阅下面的更多示例。


定义和用法

内置的<slot>元素用于放置从父组件接收到的内容。

当调用子组件时,开始标签和结束标签之间提供的内容将最终出现在<slot>元素位于该子组件内部。

一个组件可以容纳多个<slot>,并且插槽可以用name支柱。对于具有不同命名插槽的此类组件,我们可以使用v-slot将内容发送到特定插槽的指令。 (示例3

开始标签和结束标签之间的内容<slot>如果父元素未提供任何内容,元素将用作备选内容。 (示例5

可以通过以下方式向父元素提供信息<slot>道具。 (示例8

这个<slot>元素只是内容的占位符,<slot>元素本身不会呈现为 DOM 元素。


道具

Prop Description
[any] Props defined in slots create 'scoped slots' and such props are sent to the parent. Run Example »
name Names a slot so that the parent can direct content into a specific slot with the v-slot directive. Run Example »

更多示例

示例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>是,我们在周围使用一个div<slot>并设计样式<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 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>
运行示例 »

示例3

使用槽名称,可以将内容发送到特定槽。

SlotComp.vue:

<h3>Component</h3>
<div>
  <slot name="topSlot"></slot>
</div>
<div>
  <slot name="bottomSlot"></slot>
</div>

App.vue:

<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp v-slot:bottomSlot>'Hello!'</slot-comp>
运行示例 »

示例4

组件中有两个槽,发送到组件的内容最终将出现在两个槽中。

App.vue:

<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp>'Hello!'</slot-comp>

SlotComp.vue:

<h3>Component</h3>
<div>
  <slot></slot>
</div>
<div>
  <slot></slot>
</div>
运行示例 »

示例5

在插槽中使用备选内容,以便在父级未提供任何内容时呈现某些内容。

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>
运行示例 »

示例6

没有名称的插槽将是父级内容的默认插槽。

SlotComp.vue:

<h3>Component</h3>
<div>
  <slot></slot>
</div>
<div>
  <slot name="bottomSlot"></slot>
</div>

App.vue:

<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</p>
<slot-comp>'Hello!'</slot-comp>
运行示例 »

示例7

使用v-slot:default显式定义一个槽作为默认槽。

SlotComp.vue:

<h3>Component</h3>
<div>
  <slot></slot>
</div>
<div>
  <slot name="bottomSlot"></slot>
</div>

App.vue:

<h1>App.vue</h1>
<p>The component has two div tags with one slot in each.</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 槽

Vue教程:范围插槽

Vue教程:成分

Vue参考:Vue v 槽指令

Vue参考:Vue $slots 对象