一:组件的类型
1.默认插槽
2.作用域插槽
3.具名插槽
二:组件的使用
1.默认插槽
- 组件内用
<slot> </slot>
占位 - 使用组件时夹着的地方, 传入标签替换slot
需求:以前折叠面板案例,想要实现不同内容显示,我们把折叠面板里的Pan组件,添加组件插槽方式
Pan组件
<template>
<div>
<!-- 按钮标题 -->
<div class="title">
<h4>芙蓉楼送辛渐</h4>
<span class="btn" @click="isShow = !isShow">
{{ isShow ? "收起" : "展开" }}
</span>
</div>
<!-- 下拉内容 -->
<div class="container" v-show="isShow">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isShow: false,
};
},
};
</script>
<style scoped>
h3 {
text-align: center;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
border: 1px solid #ccc;
padding: 0 1em;
}
.title h4 {
line-height: 2;
margin: 0;
}
.container {
border: 1px solid #ccc;
padding: 0 1em;
}
.btn {
/* 鼠标改成手的形状 */
cursor: pointer;
}
img {
width: 50%;
}
</style>
使用组件
<template>
<div id="container">
<div id="app">
<h3>案例:折叠面板</h3>
<Pannel>
<img src="../assets/mm.gif" alt="" />
<span>我是文字哦</span>
</Pannel>
<Pannel>
<img src="../assets/mm.gif" alt="" />
<span>我是文字哦</span>
</Pannel>
<Pannel>
<div>
<p>寒雨连江夜入吴,</p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</div>
</Pannel>
</div>
</div>
</template>
<script>
import Pannel from "./Pannel";
export default {
components: {
Pannel,
},
};
</script>
<style>
#app {
width: 400px;
margin: 20px auto;
background-color: #fff;
border: 4px solid blueviolet;
border-radius: 1em;
box-shadow: 3px 3px 3px rgba(0, 0, 0, 0.5);
padding: 1em 2em 2em;
}
</style>
总结:组件内容分发技术,slot占位,使用组件时传入替换slot位置的标签
2.作用域插槽
口诀:
- 创建组件, 准备slot, 在slot上绑定属性和子组件值
- 使用组件, 传入自定义标签, 用template和v-slot=“自定义变量名”
- 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置
Pannel.vue - 定义组件, 和具名插槽, 给slot绑定属性和值
<template>
<div>
<p>这里是个Pannel-子组件, 下面是插槽位置</p>
<slot name="one" :row="slotDefault">{{ slotDefault.default1 }}</slot>
</div>
</template>
<script>
export default {
data(){
return {
slotDefault: {
default1: "无名氏",
default2: "孙红雷"
}
}
}
}
</script>
Use.vue
<template>
<div>
<!-- 夹着位置不传, slot使用默认内容"无名氏" -->
<Pannel></Pannel>
<!-- 想要改变默认内容, 但是默认数据在子组件里, 想让插槽使用就使用插槽作用域 -->
<!--
口诀: 1.创建组件, 准备slot, 在slot上绑定属性和子组件值
2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"
3. 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置
-->
<Pannel>
<template v-slot:one="scope">
{{ scope.row.default2 }}
</template>
</Pannel>
</div>
</template>
<script>
import Pannel from './Pannel'
export default {
components: {
Pannel
}
}
</script>
案例:封装一个表格组件, 在表格组件内循环产生单元格
- 创建页面index.vue
<template>
<div>
<table border="1">
<thead>
<tr>
<th>序号</th>
<th>姓名</th>
<th>年龄</th>
<th>头像</th>
</tr>
</thead>
<thead>
<tr v-for="(obj, index) in arr" :key="index">
<td>{{ index + 1 }}</td>
<td>{{ obj.name }}</td>
<td>{{ obj.age }}</td>
<td>
<slot :data="obj"></slot>
</td>
</tr>
</thead>
</table>
</div>
</template>
<script>
export default {
props: {
arr: Array
}
}
</script>
- 创建UseIndex.vue - 准备数据,传入给index.vue组件循环使用
<template>
<div>
<MyTable :arr="list">
<template v-slot="scope">
<img :src="scope.data.headImgUrl" alt="">
</template>
</MyTable>
</div>
</template>
<script>
import MyTable from "./MyTable";
export default {
components: {
MyTable
},
data() {
return {
list: [
{
name: "小传同学",
age: 18,
headImgUrl:
"http://yun.itheima.com/Upload/./Images/20210303/603f2d2153241.jpg",
},
{
name: "小黑同学",
age: 25,
headImgUrl:
"http://yun.itheima.com/Upload/./Images/20210304/6040b101a18ef.jpg",
},
{
name: "智慧同学",
age: 21,
headImgUrl:
"http://yun.itheima.com/Upload/./Images/20210302/603e0142e535f.jpg",
},
],
};
},
};
</script>
- 在App.vue里引用UseIndex.vue
总结:
1.插槽可以自定义标签,作用域插槽可以把组件内的值取出来自定义内容
2.组件内变量绑定在slot上, 然后使用组件v-slot=“变量” 变量上就会绑定slot身上属性和值
3.具名插槽
具名插槽:<slot name="名称"></slot>
其实就是在子组件中定义插槽时,给对应的插槽分别起个名字,方便后边插入父组件将内容根据name来填充对应的内容。
留下具名slot
<div class="container" v-show="isShow">
<slot name="one"></slot>
<slot name="two"></slot>
</div>
使用
<template v-slot:one>
<img src="../assets/mm.gif" alt="" />
</template>
<template #two>
<span>我是文字哦</span>
</template>
总结:
1.slot的name属性起插槽名, 使用组件时, template配合#插槽名传入具体标签
2.v-slot可以简化成#
三: 应用场景
组件的左边内容和右边内容可能会根据使用者的不同显示不同的内容,是不能写死的,我们可以通过具名插槽来做一下内容自定义优化
上面我们使用了俩个具名插槽,将来在使用组件的时候,只需要按照对应的插槽名称就可以在特定的位置插入内容,另外注意如果需要根据是否插入内容来作为判断条件,可以使用$slots.插槽名称
来获取