什么是插槽
slot 【插槽】, 是 Vue 的内容分发机制, 组件内部的模板引擎使用slot 元素作为承载分发内容的出口。slot 是子组件的一个模板标签元素, 而这一个标签元素是否显示, 以及怎么显示是由父组件决定的。
VUE中slot【插槽】的分类与应用
插槽有三种:默认插槽、具名插槽、作用域插槽。
(1)默认插槽
语法:<slot></slot>
示例:
在子组件中定义一个默认插槽
<template>
<div>
<h2>{{ title }}</h2>
<slot></slot>
</div>
</template>
在开发中我们经常使用到组件之间的传值,但很多情况涉及到的都是数据属性的传值,现在如果是这种情况:想让父组件定义的 p 标签传给子组件并显示,可以在子组件中定义一个默认插槽
<template>
<div class="about">
<h1>This is an Parent page</h1>
<children>
<!-- 一个p标签的dom结构 -->
<p>子组件标签之间</p>
</children>
</div>
</template>
<script>
import Children from './Children.vue'
export default {
components: {
Children
},
data () {
return {}
}
}
</script>
展示效果
(2)具名卡槽
在子组件中定义插槽时,给对应的插槽分别起个名字,方便后边插入父组件将根据 name 来填充对应的内容。这种有name属性的卡槽就是具名卡槽。
为具名插槽提供内容:
在向具名插槽提供内容的时候,我们可以在一个 <template>
元素上使用 v-slot 指令,并以 v-slot 的参数的形式指定元素需要放在哪个插槽中。
【语法】<template v-slot:插槽的name> 需要向插槽中放入的内容 </template>
具名插槽的简写形式:
跟 v-on 和 v-bind 一样,v-slot 也有缩写,即把参数之前的所有内容 (v-slot:
) 替换为字符 #
。例如 v-slot:header
可以被重写为 #header
【语法】<template #插槽的name> 需要向插槽中放入的内容 </template>
【注】
- 使用 v-slot 指令指定元素放在哪个插槽中,必须配合
<template>
元素,且一个<template>
元素只能对应一个预留的插槽,即不能多个<template>
元素都使用 v-slot 指令指定相同的插槽。 - 在 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的 attribute。
- 使用 slot 属性指定元素放置的插槽:slot="插槽的name",slot 属性可以直接写在元素标签上,即 slot 属性不用必须与<template> 元素配合,且不同的标签可以使用 slot 属性指定相同的插槽,使用 slot 属性指定了相同的插槽都会被放入一个插槽中,后面的元素会被追加在前面放入插槽的元素后。
示例:
在子组件中,定义两个具名插槽:
<template>
<div>
<h3>Com 组件</h3>
<slot name="header"></slot>
<slot name="bottom"></slot>
</div>
</template>
<script>
export default {
name: 'Com'
}
</script>
父组件示例代码
<template>
<div>
<h1>App 组件</h1>
<Com>
<!-- 指定需要向子组件的插槽区域放入的元素 -->
<!-- 需要放入插槽的元素写在组件标签内 -->
<!-- <div>插槽的内容</div> -->
<template v-slot:header>
<div>头部区域</div>
</template>
<template v-slot:default>
<div>默认区域</div>
</template>
<template v-slot:bottom>
<div>bottom区域</div>
</template>
</Com>
</div>
</template>
<script>
import Com from './Com.vue'
export default {
name: 'App',
components: { Com }
}
</script>
(3)作用域插槽
在封装组件的过程中,可以为预留的<slot>
插槽绑定 props 数据,这种带有 props 数据的<slot>
叫做“作用域插槽”。
作用域插槽,要显示的数据已经在组件中,以什么样的样式显示数据(用什么标签和标签的样式),可以由组件的使用者进行指定
【语法】<slot :自定义的name=data中的属性或对象></slot>
注:为作用域插槽指定插槽内的元素必须使用 <template>
标签。
获取插槽绑定 props 数据的方法:
1.scope="接收的变量名":<template scope="接收的变量名">
2.slot-scope="接收的变量名":<template slot-scope="接收的变量名">
3.v-slot:插槽名="接收的变量名":<template v-slot:插槽名="接收的变量名">
子组件示例
<template>
<div>
<h3>Com 组件</h3>
<!-- 为组件的使用者预留的区域 -->
<!-- :infomation="info" 未来要进行渲染在插槽位置的数据 -->
<!-- 怎么样渲染数据由组件的使用者决定 -->
<slot :infomation="info" :msg="msg"></slot>
</div>
</template>
<script>
export default {
name: 'Com',
data() {
return {
info: { name: 'zs', age: 23 },
msg: 'hello vue'
}
}
}
</script>
父组件示例
<template>
<div>
<h1>App 组件</h1>
<Com>
<!-- 指定需要向子组件的插槽区域放入的元素 -->
<!-- 需要放入插槽的元素写在组件标签内 -->
<!-- val 接收组件中要在插槽位置渲染的数据 -->
<!-- val 组件通过 props 向插槽中传入的数据 -->
<template #default="val"> {{ val }} </template>
</Com>
</div>
</template>
<script>
import Com from './Com.vue'
export default {
name: 'App',
components: { Com }
}
</script>
此文章借鉴了一下博主的优秀文章:
原文链接