插槽
插槽(Slot)是 vue 为组件的封装者提供的能力。
允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。
默认插槽 slot
需求: 要在页面中显示一个对话框, 封装成一个组件
通过父传子, 固然可以完成一定层面的组件的定制, 但是自定义性较差,
如果希望能够自定义组件内部的一些结构 => 就需要用到插槽
插槽作用: 用于实现组件的内容分发, 通过 slot 标签, 可以接收到写在组件标签内的内容
插槽:slot 作用:占位置
基本示例:
<my-dialog>
<p>请输入正确的手机号码</p>
</my-dialog>
my-dialog.vue
<template>
<div class="my-dialog">
<div class="header">
<h3>友情提示</h3>
</div>
<div class="content">
<slot></slot>
</div>
<div class="footer">
<button>关闭</button>
</div>
</div>
</template>
<script>
export default {
}
</script>
<style lang="less" scoped>
.my-dialog {
width: 400px;
padding: 10px 20px;
border: 3px solid #000;
border-radius: 5px;
margin: 10px;
}
</style>
后备内容 (默认值)
封装组件时,可以为预留的 <slot> 插槽提供后备内容(默认内容)。
如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。
<template>
<div class="my-dialog">
<div class="header">
<h3>友情提示</h3>
</div>
<div class="content">
<slot>这是后备内容</slot>
</div>
<div class="footer">
<button>关闭</button>
</div>
</div>
</template>
具名插槽
插槽的分类:
1 默认插槽(匿名插槽)
<slot></slot> 只要没有具体分发的内容, 都会给到默认插槽
<slot name="default"></slot> 是默认插槽完整的写法 和 <slot></slot> 完全等价
2 具名插槽: 具有名字的插槽 (配置了名字), 可以实现定向分发
一旦配置了名字, 只会接收对应的内容, 不是分发给他的, 就不要
具名插槽的使用步骤
(1) 给插槽起名字
<div class="header">
<slot name="header"></slot>
</div>
<div class="content">
<slot>这是后备内容</slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
(2) 需要使用 template 标签, 将内容包裹成一个整体
(3) 通过 v-slot:插槽名, 指定具体分发给谁
<my-dialog>
<template v-slot:header>
<h3>这是大标题</h3>
</template>
<template v-slot:default>
<p>这是内容</p>
</template>
<template v-slot:footer>
<button>确认</button>
<button>取消</button>
</template>
</my-dialog>
具名插槽的简写
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:) 替换为字符 #。
例如 v-slot:header 可以被简写为 #header
<my-dialog>
<template #header>
<h3>这是大标题</h3>
</template>
<template #default>
<p>这是内容</p>
</template>
<template #footer>
<button>确认</button>
<button>取消</button>
</template>
</my-dialog>
作用域插槽
作用域插槽: 定义 slot 插槽的同时, 是可以传值的, 将来在分发内容时, 可以使用
- 给 slot 标签, 以 添加属性的方式传值
<slot name="bottom" :yes="yes" :no="no" money="100"></slot>
- 所有添加的属性, 都会被收集到一个对象中
{ yes: '确认', no: '取消', money: '100' }
- 在template中, 通过
v-slot:插槽名= "obj"接收
<template #bottom="obj">
<!-- {{ obj }} -->
<button>{{ obj.yes }}</button>
<button>{{ obj.no }}</button>
<button>{{ obj.money }}</button>
</template>
- 可以使用解构赋值简化数据的接收
<template #bottom="{ yes, no, money }">
<button>{{ yes }}</button>
<button>{{ no }}</button>
<button>{{ money }}</button>
</template>