插槽,可以简单理解为在当前组件留下一个位置为使用该组件时接收一些非固定的内容

Vue2.6之后,插槽指令统一为v-slot, 缩写为#
详见 官方文档

具名插槽

当想在子组件的不同位置插入不同的内容时,需要给每个位置都定义一个插槽名

1
2
3
4
5
6
7
8
9
10
11
12
// base-component组件
<div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
<main>
<footer>
<slot name="footer"></slot>
<footer>
</div>

上面组件定义了三个插槽,中间的插槽未定义插槽名,它会带有隐含的名字 default,可使用该名字或者省略,使用插槽指令的缩写形式不能省略插槽名。
想要向具名插槽提供内容,需要用一个 template元素上使用 v-slot指令提供名称。

1
2
3
4
5
6
7
8
9
10
11
<base-component>
<template v-slot:header>
<h1>Header</h1>
</template>

<p>This is main. </p>

<template v-slot:header>
<p>Footer</p>
</template>
</base-component>

渲染出来的结果是三段内容分别插入 base-component组件的三处插槽位置。

另外插槽内还可以定义默认内容,使用组件插槽时不插入内容就渲染默认内容,有新内容就覆盖插槽中默认的内容。

作用域插槽

有时插入插槽的内容需要访问子组件数据,就需要在插槽中绑定数据

1
2
3
4
5
6
// base-component组件
<span>
<slot name="userName" v-bind:user="user">
{{ user.lastName }}
</slot>
</span>

绑定在插槽中的属性被称为插槽 prop,当在父组件中使用插槽时,用带值的v-slot定义插槽 prop的名字来获取子组件上的数据

1
2
3
4
5
<base-component>
<template v-slot:userName="scope">
{{ scope.user.firstName + scope.user.lastName }}
</template>
</base-component>

这个例子中将包含插槽 prop的对象名命名为scope,这个名字可以自定义.

另外插槽名字也是可以省略的,对与默认名插槽获取插槽作用域可以v-slot="scopeName"获取插槽 prop对象。

解构 插槽 prop

在支持的环境下可以使用es6的解构来传入插槽 propv-slot={ user }便可直接使用子组件作用域的user对象。

动态插槽名

1
2
3
4
5
<base-component>
<template v-slot:[dynamicSlotName] >
...
</template>
</base-component>