插槽
- 组件的插槽是为了让我们封装的组件更加具有扩展性
- 让使用者可以决定组件内部的一些内容到底展示什么
- 封装插槽的方法:抽取共性,保留不同
- 最好的封装方式就是将共性抽取到组件中,将不同暴露为插槽
- 一旦预留了插槽,就可以让使用者根据自己的需求,决定插槽中插入什么内容
- 插槽的作用是 混合父组件的内容与子组件自己的模版
<div id='father'>
<h1>{{ name }}</h1>
<son></son>
</div>
<template id='son'>
<div>
<h1>{{ name }}</h1>
</div>
<template>
const son = {
template:'#son',
data() {
return {
name:'我是儿子'
}
}
}
const father = new Vue({
el:"#father",
data:{
name:'我是爹'
},
components:{ son }
})
打印到页面上看看
很好,爹和儿子都出来了
我们使用儿子的时候,是这样使用的
<div id='father'>
<!-- 省略 -->
<son></son>
</div>
可是,如果我们这样写,这一串文字能出现么?
<son>插槽要来了插槽要来了</son>
打印一下
-
其实不能出现的原因我们也知道,在页面渲染的时候,子组件,也就是template标签,把正在使用的son标签一整个给替换了,所以,那一串文字并没有出现
-
这样做明显不符合组件复用性的思想
-
别怕,enter妹妹手把手教你做
-
其实也很简单,我们只需要这么做
<template id="son">
<div>
<h1>{{ name }}</h1>
<slot></slot>
</div>
</template>
- 添加了slot标签之后就能显示那一串文字了
- 爱学习的弟弟们肯定已经翻开了网易有道词典,其实slot这个单词的意思就是位置,狭槽的意思
打印到页面上看一下
具名插槽
-
顾名思义,就是有名字的插槽
-
上代码,如果我给子组件定义三个插槽,那么那一串文字插在哪里呢?
-
先把那一串文字用p标签包起来
<div di='father'>
//...
<son><p>插槽要来了</p></son>
</div>
<template id="son">
<div>
<h1>{{ name }}</h1>
<slot></slot>
<slot></slot>
<slot></slot>
</div>
</template>
实践是检验真理的唯一标准,我们打印到页面看看
- 可以看出来,我们son标签里有三个插槽,但是只提供了一个插头(p标签)
- 这个插头会插上所有的插槽
- 我们也给他来三个插头
<div id="father">
<h1>{{ name }}</h1>
<son>
<p>我是下面的白熊</p>
<p>我是上面的棕熊</p>
<p>我是中间的熊猫</p>
</son>
</div>
enter妹妹可喜欢咱们裸熊了,顺便给你们安利一下
打印到页面看看
- 可以看出来这三个p标签都用复用了三次
- 那么怎么避免这种情况,还能让三个小熊按照顺序摞在一起呢?
- 这时候就可以使用具名插槽了
<div id="father">
<h1>{{ name }}</h1>
<son>
<p slot='bottom'>我是下面的白熊</p>
<p slot="top">我是上面的棕熊</p>
<p slot="center">我是中间的熊猫</p>
</son>
</div>
<template id="son">
<div>
<h1>{{ name }}</h1>
<slot name='top'></slot>
<slot name='center'></slot>
<slot name='bottom'></slot>
</div>
</template>
- 儿子组件的slot插槽添加name属性
- 父亲组件使用的在标签里添加slot属性
- 两个属性一致就会插到对应的插槽里面
看一下页面效果
插槽默认标签
- 在使用具名插槽的时候,还可以设置一个默认标签
- 比如我想在bottom插槽里设置一个默认值button按钮
- 当这个插槽没人插的时候,button就会显示出来
- 可以这么写
<!-- <p slot='bottom'>我是下面的白熊</p> -->
<slot name='bottom'><button>按钮</button></slot>
看一下页面效果
插槽用哪里的数据
- 当在组件里面使用变量的时候都会先看看这个变量是哪个模板里面的,使用对应模板的Vue实例里面的变量
让白熊后面跟一个num
<p slot='bottom'>我是下面的白熊{{ num }}</p>
在儿子组件里设置一个num值为50
const son = {
template:"#son",
data() {
return {
name:'我是儿子',
num:50
}
}
}
在爹组件里设置一个num值为10
const father = new Vue({
el:'#father',
data:{
name:'我是爹',
num:10
},
components:{ son }
})
那么问题来了,白熊会用哪一个num呢?
打印到页面上看一下