插槽就是子组件预留给父组件放置内容的空间,如果没有插槽,那么我们在父组件中使用子组件时,往子组件里添加内容是无效的。
父组件:
<template>
<div style="text-align: center">
<todo-item>
<!-- 子组件标签里的内容将不会显示 -->
<span>这里是父组件DOM</span>
</todo-item>
</div>
</template>
那么有什么办法可以让子组件标签像div一样可以在里面放置内容吗?当然是有的,就是 我们要介绍的插槽slot。
slot
如果我们在子组件中添加插槽,那么放入子组件标签中的内容就会被加载到slot中。
子组件:
<template>
<div style="text-align: center" class='child'>
<h3>这是子组件</h3>
<!-- 像这样添加slot标签即可 -->
<slot></slot>
</div>
</template>
这样父组件中添加的内容将会替换掉slot,相当于
子组件:
<div style="text-align: center" class='child'>
<h3>这是子组件</h3>
<!-- slot标签会被替换掉 -->
<span>这里是父组件DOM</span>
</div>
每一个子组件都应该有一个像这样不带名字的插槽,称为单个插槽。
同时我们也可以增加一些带有名字的插槽,控制DOM内容的不同位置,带有name属性的插槽称为具名插槽。
子组件
<template>
<div style="text-align: center" class='child'>
<slot name="top"></slot>
<h3>这是子组件</h3>
<slot></slot>
<hr style="margin-top: 20px">
<slot name="down"></slot>
</div>
</template>
父组件中要添加slot属性:
<template>
<div style="text-align: center">
<todo-item>
<span class="father-dom">这里是父组件DOM</span>
<span slot="down">这是底部</span>
<span slot="top">这是顶部</span>
</todo-item>
</div>
</template>
不管父组件中增加的DOM先后顺序如何,具名插槽总是对应到同名的子组件位置处,剩下的对应到单个插槽处。如果在父组件中给了slot属性,但是子组件中并没有该插槽,那么那个标签将不会显示。
slot-scope
这个属性是给父组件中插入在子组件标签中的DOM使用的,可以获取插槽上的属性值。
父组件
<template>
<div style="text-align: center">
<todo-item :message="message">
<template slot-scope="scope">
<span>{{scope}}</span><br>
<span>{{scope.data}}</span>
</template>
</todo-item>
</div>
</template>
子组件:
<template>
<div style="text-align: center" class='child'>
<h3>这是子组件</h3>
<slot :data="message"></slot>
</div>
</template>
父组件中slot-scope绑定的scope对应的数据就是子组件中slot上的data。