插槽的概念
如果在使用组件的时候,在组件的内部放入一些内容,组件如果没有定义插槽的话,组件是不知道要放在那里的,所以就不会被显示。
如果组件内部定义了这个区域,哪个这个组件中放的内容就会被渲染到指定的位置上
入门案例
Left组件定义:
<template>
<div class="left-container">
<h3>Left 组件</h3>
<hr />
<!-- 声明一个插槽区域 -->
<slot></slot>
</div>
</template>
Left组件使用:
<div class="box">
<Left>
<p>这是一个在Left组件的内容区域,声明的 p 标签</p>
</Left>
</div>
效果如下:
插槽的基本使用
插槽名称的定义
Left组件定义
<template>
<div class="left-container">
<h3>Left 组件</h3>
<hr />
<!-- 声明一个插槽区域 -->
<!-- vue 官方规定: 每一个slot插槽,都要有一个 name 名称 -->
<!-- 缺省:默认为default -->
<slot name="default"></slot>
</div>
</template>
插槽的使用
默认情况下
<Left>
<!-- 默认情况下,在使用组件的时候,提供的内容都会填充到名字为default的插槽中-->
<p>这是一个在Left组件的内容区域,声明的 p 标签</p>
</Left>
指定插槽的情况:
使用 v-slot : 该指令只能使用在 components 或者 中
<Left>
<!-- 默认情况不指定,会填充到default的插槽中 -->
<!-- 如需指定,需要使用 v-slot: 指令 -->
<!-- v-slot: 后面需要跟插槽名称 -->
<!-- v-slot: 不能直接用在元素身上,需要在templat标签上 -->
<!-- templat 标签是一个虚拟标签,只起到包裹性质的作用,不会被渲染成任何html元素 -->
<!-- v-slot: 的简写形式为#,如 v-slot:default #default -->
<template v-slot:default>
<p>这是一个在Left组件的内容区域,声明的 p 标签</p>
</template>
</Left>
slot 的后备内容
封装组件时,提供默认内容。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。
<slot name="default">
<h6>这是default 插槽的默认内容</h6>
</slot>
具名插槽
带有名字的插槽
组件定义:
<template>
<div class="article-container">
<!-- 文章的标题 -->
<div class="header-box">
<slot name="header"></slot>
</div>
<!-- 文章的内容 -->
<div class="content-box">
<slot name="content"></slot>
</div>
<!-- 文章的作者 -->
<div class="footer-box">
<slot name="footer"></slot>
</div>
</div>
</template>
<script>
export default {
name: 'Article'
}
</script>
<style lang="less" scoped>
.article-container {
> div {
min-height: 150px;
}
.header-box {
background-color: pink
}
.content-box {
background-color: lightblue
}
.footer-box {
background-color: lightsalmon
}
}
</style>
使用:
<Article>
<template #header>
<h1>这是一首诗</h1>
</template>
<template #content>
<div>
<p>啊,大海,全是水</p>
<p>啊,蜈蚣,全是退</p>
<p>啊,辣椒,净辣嘴</p>
</div>
</template>
<template #footer>
<div>作者: xxx</div>
</template>
</Article>
作用域插槽
插槽向使用处传数据
组件封装:
<!-- 文章的内容 -->
<div class="content-box">
<!-- 为 slot 提供属性对应的值,这种叫作用域插槽-->
<slot name="content" msg="hello vue.js" :user="userinfo"></slot>
</div>
<script>
data(){
return {
userinfo: {
name: 'zs',
age: 20
}
}
}
</script>
使用该组件时
接收slot的作用域对象,规范使用scope接
<template #content="scope">
<div>
<p>啊,大海,全是水</p>
<p>啊,蜈蚣,全是退</p>
<p>啊,辣椒,净辣嘴</p>
<p>{{ scope.msg }}</p>
<p>{{ scope.user }}</p>
</div>
</template>
还有一种将scope解构的写法
<template #content="{ msg, user }">
<div>
<p>啊,大海,全是水</p>
<p>啊,蜈蚣,全是退</p>
<p>啊,辣椒,净辣嘴</p>
<p>{{ msg }}</p>
<p>{{ user }}</p>
</div>
</template>