例子讲解Vue.js的slot分发

时间:2022-12-21 13:06:11

slot出现的目的

当我们使用我们自定义的组件时,我们希望我们自定义的组件能够适应很多场景,我们希望组件中能够在不同的场景有着不同的内容
而之前我们学过父组件与子组件之间的通信,它们是通过Vue的全局组件注册中的props来实现的
但是这样显得太过繁琐,而且当自组件中需要显示的内容是父组件中没有的,那就很尴尬了
所以,slot就产生了

例子讲解

统一的CSS

.container{
margin-top: 30px;
height: 200px;
}

HTML1

<my-son>
<h1 slot="header">我是header的内容</h1>
<p>我只是文本内容</p>
<p>我只是文本内容</p>
<h2 slot="footer">我是footer的内容</h2>
</my-son>

JS

Vue.component("my-son", {
template: "<div class='container'></div>"
});
new Vue({
el: "#box"
});

结果显示
例子讲解Vue.js的slot分发

如图所示,我定义了一个组件my-son,当我在页面中使用它,并在其中添加所需的内容,它无效

HTML2

<my-son>
<h1 slot="header">我是header的内容</h1>
<p>我只是文本内容</p>
<p>我只是文本内容</p>
<h2 slot="footer">我是footer的内容</h2>
</my-son>

JS

Vue.component("my-son", {
template: '<div class="container">\
<header>\
<slot name="header"></slot>\
</header>\
<main>\
<slot></slot>\
</main>\
<footer>\
<slot name="footer"></slot>\
</footer>\
</div>',
});
new Vue({
el: "#box"
});

结果显示
例子讲解Vue.js的slot分发

如图所示,当我们在子组件中添加了slot标签,那么我们在使用自定义组件的时候,我们就可以在组件标签中写入我们需要显示的内容

HTML3

<div id="box">
<div class="parent">
<my-son>
<span>Hello from parent</span><br/>
</my-son>
</div>
</div>

JS

Vue.component("my-son", {
template: '<div class="container">\
<slot text="hello from child"></slot>\
<slot text="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"></slot>\
<slot text="I am a child, how is it"></slot>\
</div>',
});
new Vue({
el: "#box"
});

结果显示
例子讲解Vue.js的slot分发

如图所示:在使用组件时,组件标签中的内容会匹配组件中的slot标签,如果slot标签都没有具体的名字(name属性)的话,那么是有多少slot标签,就匹配多少次

HTML4

<div id="box">
<div class="parent">
<my-son>
<span>Hello from parent</span><br/>
</my-son>
</div>
</div>

JS

Vue.component("my-son", {
template: '<div class="container">\
<slot name="text1" text="hello from child"></slot>\
<slot name="text2" text="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"></slot>\
<slot name="text3" text="I am a child, how is it"></slot>\
</div>',
});
new Vue({
el: "#box"
});

结果显示
例子讲解Vue.js的slot分发

注意:具名slot是给组中的slot赋予一个name属性,在使用该组件时,只有拥有该属性的标签才能匹配,如上述例子,html文档中没有苏醒slot=text1,slot=text2,slot=text3的标签,所以不能匹配组件中的slot标签,即不能将组件中的内容给加载呈现出来

HTML5

<div id="box">
<div class="parent">
<my-son>
<template scope="props">
<span>
{{ props.text }}</span>
</template>
</my-son>
</div>
</div>

JS

Vue.component("my-son", {
template: '<div class="container">\
<slot text="hello from child"></slot>\
<slot text="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"></slot>\
<slot text="I am a child, how is it"></slot>\
</div>',
});
new Vue({
el: "#box"
});

结果显示
例子讲解Vue.js的slot分发

内容的逆向传送:之前我们将的都是将内容传送到自定义的组件中slot中的实现,此例讲的是如何将组件中slot中的内容传送到外部,然后再调用
这里就用到了scope和template标签
template标签必须放在自定义标签的内部使用
然后定义template标签的scope属性,给内部slot标签的text属性的内容定义一个别名,然后使用这个别名直接调用
这里定义的是props这个名称,我们也可以改为a、b、c等等的名称,只是一个代号,没有规定非得使用props

希望能给你帮助:)