前言
这段时间一直在研究vue的用法,在学习过程中发现,官方文档对于插槽(slot)的描述实在有点过于简练,费了我一番功夫才算弄明白,所以特地在此进行一番总结,也方便其他初学者了解该功能的用法。
一、插槽是什么?
当我们进行组件的开发时,有时会遇到这样的需求:我希望向子组件传递一小段模板,将它展示在子组件的特定位置,而不希望模板的内容受到子组件的限制。
举个最简单的例子:向页面布局组件传入页面内容,让内容展示在正文部分。这种时候,就是插槽派上用场的时候。
通俗的说法就是,把模板当作参数传给子组件,子组件不关心模板有什么内容,只关心把它显示在哪里。
二、具体用法
1.默认插槽
只需要传递一段模板时,可以这么写:
父组件:
<template>
<Child>
<div>插槽展示内容</div>
</Child>
</template>
子组件:
<template>
<div>子组件内容</div>
<slot></slot>
</template>
在子组件中的<slot></slot>
,正是插槽内容要显示的位置。经过组合后,最终显示出来的其实是这样的结构:
<template>
<div>子组件内容</div>
<div>插槽展示内容</div>
</template>
2.具名插槽
默认插槽用起来很简单,但有时并不能满足需求:要是我想传递两个插槽,并显示在子组件的不同位置,那要怎么做?答案就是具名插槽。
给每个插槽模板借助v-slot:插槽名
指定一个名字,子组件就可以通过名字来区分不同的模板了。(老版本使用solt
属性,用法是一致的,新版本已废弃)
父组件:
<template>
<Child>
<template v-slot:header>头部插槽</div>
<template v-slot:content>内容插槽</div>
<template v-slot:footer>尾部插槽</div>
</Child>
</template>
子组件:
<template>
<div>子组件内容</div>
<header>
<slot name="header"></slot>
</header>
<main>
<slot name="content"></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</template>
组合后结果:
<template>
<div>子组件内容</div>
<header>头部插槽</header>
<main>内容插槽</main>
<footer>尾部插槽</footer>
</template>
3.作用域插槽
作用域插槽的概念可能有点晦涩,毕竟命名上就不是很直观。简单形容的话,就是父组件在插槽模板里使用子组件内部的数据。
直接调用当然是行不通的,因为插槽的内容是在父级作用域中编译的,但可以利用作用域插槽进行数据的传递。
在父组件中使用v-slot
获得子组件绑定到插槽上的数据(从2.6.0开始原本的slot-scope
写法遭到废弃):
<template>
<Child>
<template v-slot="slotProps">
{{slotProps.id}}
</template>
</Child>
</template>
在子组件中使用v-bind
将数据绑定到插槽上:
<template>
<div>子组件内容</div>
<slot v-bind:myData="myData"></slot>
</template>
在这个例子里,myData是子组件的数据,借助作用域插槽,父组件获得了绑定的myData,并将其id显示了出来。