1.简介
- 用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容
- 通过插槽定制组件的结构,可以提高组件的可复用性
- 父组件的变量,函数都可以在插槽中使用
2.默认插槽
2.1 使用:
在父组件内注册使用子组件,在组组件内添加<slot></slot>,在父组件中引用的子组件上,写的任何内容都会被渲染到子组件的<slot></slot>中
// 子组件
<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>
2.2 注意:
- 默认插槽只能有一个
- 插槽内样式父子组件都可以直接控制
2.3 默认内容(后备内容)
<slot>夹着的内容是默认显示内容, 如果不给插槽slot传东西, 则在原地显示默认内容 ,如果传递了插槽内容,则传递的内容优先级最高
<slot>默认内容</slot>
3.具名插槽
3.1 应用场景
当一个组件内有2处以上需要外部传入标签的地方,传入的标签可以分别派发给不同的slot位置
3.2 语法
子组件内设置具名slot <slot name="one"></slot>
父组件: <template v-slot:one>
// 子组件
<div class="container" v-show="isShow">
<slot name="one"></slot>
<slot name="two"></slot>
</div>
// 父组件
<Pannel2>
<template v-slot:one>
<img src="../assets/mm.gif" alt="" />
</template>
<template v-slot:two>
<span>我是文字哦</span>
</template>
</Pannel2>
注意: v-bind可以省略成: v-on: 可以省略成@ 那么v-slot: 可以简化成 #。所以可以写成如下格式
<Pannel2>
<!-- 简化写法 -->
<template #one>
<div>
<p>寒雨连江夜入吴,</p>
<p>平明送客楚山孤。</p>
<p>洛阳亲友如相问,</p>
<p>一片冰心在玉壶。</p>
</div>
</template>
<template #two>
<img src="../assets/mm.gif" alt="" />
</template>
</Pannel2>
4.作用域插槽
4.1 使用步骤
- 创建子组件, 准备slot, 在slot上绑定属性和子组件值
- 使用子组件, 传入自定义标签, 用template和v-slot="自定义变量名"
- 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置
4.2 代码
//子组件
<template>
<div>
<p>这里是个Pannel3-子组件, 下面是插槽位置</p>
<slot name="one" :row="slotDefault">{{ slotDefault.default1 }}</slot>
</div>
</template>
<script>
export default {
data(){
return {
slotDefault: {
default1: "无名氏",
default2: "孙红雷"
}
}
}
}
</script>
// 父组件
<template>
<div>
<!-- 夹着位置不传, slot使用默认内容"无名氏" -->
<Pannel3></Pannel3>
<!-- 想要改变默认内容, 但是默认数据在子组件里, 想让插槽使用就使用插槽作用域 -->
<!--
口诀: 1.创建组件, 准备slot, 在slot上绑定属性和子组件值
2. 使用组件, 传入自定义标签, 用template和v-slot="自定义变量名"
3. 自定义变量名会自动绑定slot上所有属性, 就可以使用子组件内值, 并替换slot位置
-->
<Pannel3>
<template v-slot:one="scope">
{{ scope.row.default2 }}
</template>
</Pannel3>
</div>
</template>
<script>
import Pannel3 from './Pannel3'
export default {
components: {
Pannel3
}
}
</script>