目录

✨ Vue Slot 插槽

# slot 插槽

  • 插槽是一种可以让父组件在子组件的指定位置插入一个 HTML 结构的方式,也是一种组件之间的通信方法,适用于父组件向子组件传输。
  • 分三种插槽:默认插槽、具名插槽、作用域插槽。

🌰 插槽的使用例子:(实现如下图的分类目录)

image-20220406232609871

在主组件 App 组件中存储数据,分类 Category 组件展示数据。

🌰 **默认插槽的使用例子**:	
  • 在父组件 App 中:
<div class="container">
  <Category :listData="films" title="电影">
    <video controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
  </Category>
  <Category title="游戏">
    <ul>
      <li v-for="(g,index) in games" :key="index">{{ g }}</li>
    </ul>
  </Category>
  <Category :listData="cats" title="猫咪">
    <img src="http://placekitten.com/500/300" alt="">
  </Category>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
  • Category 组件中:
<template>
  <div class="category">
    <h3>{{ title }}分类</h3>
    <slot>当没有传递具体结构时的默认值</slot>
  </div>
</template>
1
2
3
4
5
6
🌰 **具名插槽的使用例子**:具名插槽给 `slot` 标签添加 `name` 属性用于标识不同的 `slot` 标签。

实现如下图的效果,可以使用两个插槽实现,此时需要区分两个插槽。

image-20220406233104275

  • 在父组件 App 中:
<template>
  <div class="container">
    <Category :listData="films" title="电影">
      <video slot="center" controls src="http://clips.vorwaerts-gmbh.de/big_buck_bunny.mp4"/>
      <template v-slot:footer>
        <div class="foot">
          <a href="#">经典电影</a>
          <a href="#">热门电影</a>
          <a href="#">推荐电影</a>
        </div>
        <h4>欢迎观看</h4>
      </template>
    </Category>
    <Category title="游戏">
      <ul slot="center">
        <li v-for="(g,index) in games" :key="index">{{ g }}</li>
      </ul>
      <div class="foot" slot="footer">
        <a slot="footer" href="#">单机游戏</a>
        <a slot="footer" href="#">网络游戏</a>
      </div>
    </Category>
    <Category :listData="cats" title="猫咪">
      <img slot="center" src="http://placekitten.com/500/300" alt="">
      <a slot="footer" href="#">更多猫咪</a>
    </Category>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
  • Category 组件中:
<template>
  <div class="category">
    <h3>{{ title }}分类</h3>
    <!--<ul>
       <li v-for="(item, index) in listData" :key="index">{{ item }}</li>
    </ul>-->
    <slot name="center">当没有传递具体结构时的默认值</slot>
    <slot name="footer">当没有传递具体结构时的默认值</slot>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10

🌰 作用域插槽例子:
当数据在组件的自身,但根据数据生成的结构不在该组件而在父组件决定。(如下例子,当 games 数据在 Category 组件中,但是使用数据便利出来的结构由 App 组件决定)

  • App 组件中:

决定的结构不一样,但是使用的数据一样:

<template>
  <div class="container">
    <Category title="游戏">
      <template scope="data">
        <ul>
          <li v-for="(g,index) in data.games" :key="index">{{ g }}</li>
        </ul>
      </template>
    </Category>

    <Category title="游戏">
      <template scope="{games, msg}">
        <ol>
          <li style="color:red" v-for="(g,index) in games" :key="index">{{ g }}</li>
        </ol>
        <h4>{{ msg }}</h4>
      </template>
    </Category>

    <Category title="游戏">
      <template slot-scope="{games}">
        <h4 v-for="(g,index) in games" :key="index">{{ g }}</h4>
      </template>
    </Category>
  </div>
</template>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

使用 slot-scope 标签可以支持结构赋值,(虽然使用 scope 也可以实现,但已被 slot-scope 取代这种写法)

  • Category 组件中:
<template>
  <div class="category">
    <h3>{{ title }}分类</h3>
    <slot :games="games" msg="hello">当没有传递具体结构时的默认值</slot>
  </div>
</template>
1
2
3
4
5
6
📢 上次更新: 2022/09/02, 10:18:16