在Java等语言里有个泛型类型参数可以让你传入任何类型,然后对泛型统一处理。vue里的slot我个人感觉与之类似,它的功能就是让你往组件里传入自定义的html、其他组件等,相当于是一种泛型组件,可以让你统一处理一些相似又有不同的地方。

下面这个导航栏的例子会便于理解

<template>
  <nav class="nav-bar">
    <div class="left" @click="goBack">
      <slot name="left">
        <img src="" alt="left"/>
      </slot>
    </div>
    <div class="center">
      <slot></slot>
    </div>
    <div class="right">
      <slot name="right"></slot>
    </div>
  </nav>
</template>

<script>
export default {
  name: "NavBar",
  methods: {
    goBack() {
      // 返回到上一级
    }
  }
}
</script>

<style scoped>
.nav-bar {
  background: var(--color-tint);
  color: #FFFFFF;
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  z-index: 9;
  height: 45px;
  line-height: 45px;
  text-align: center;
  box-shadow: 0 2px 0 rgba(100, 100, 100, 0.1);
  display: flex;
}

.left, .right {
  width: 60px;
}

.center {
  flex: 1;
}

.left img {
  width: 45px;
  padding: 12px;
}
</style>

上面这个案例中left的div放了一个slot并设置了一个name,这被称为具名插槽,没有设置name的会有个默认名default

使用插槽替换时如果有多个插槽并且有具名插槽则需要用template的方式,使用方式如下:

<template>
  <div>
    <nav-bar>
      <template v-slot:default>替换所有的默认插槽</template>
    </nav-bar>

    <nav-bar>
      <template v-slot:left>替换所有name为left的插槽</template>
    </nav-bar>

    <nav-bar>
      <template v-slot:right>替换所有name为right的插槽</template>
    </nav-bar>
  </div>
</template>

只有在只存在默认插槽的情况下才可以在其他的标签、组件上使用v-slot,默认的插槽也可以缩写为v-slot

插槽的缩写

v-bind可以缩写为:v-on可以缩写为@,插槽v-slot也可以缩写为#

具名插槽可以缩写为#left#right,但是默认插槽不能只写个#,必须指定具名参数,可以是#default

动态插槽名

针对动态的插槽名可以使用v-slot:[dynamicName]

<my-slot>
  <template v-slot:[dynamicName]>
    ...
  </template>
</my-slot>