vue插槽(slot)详解
1.什么是插槽:插槽可以让我们在自定义组件的时候把一部分内容预留出来,留给使用该组件的人去自定义,同时我们还可以传递一些数据供其使用。2.插槽是定义:格式:<slot name="插槽名称" :xxx="数据1" :yyy="数据2"></slot><!--说明:1.name可以不写,默认值为"default",这种插槽称为不具名插槽,但是...
·
1.什么是插槽:
插槽(slot)可以让我们在自定义组件的时候把一部分内容预留出来,留给使用该组件的人去自定义,同时我们还可以传递一些数据供其使用。
2.插槽的定义:
- 格式:
<slot name="插槽名称" :xxx="数据1" :yyy="数据2">默认内容</slot>
- name可以不写,默认值为"default",这种插槽称为不具名插槽或者默认插槽,但是只能有一个,有name的称为具名插槽
- 传参和正常组件的数据绑定没有区别,数据格式不限,个数不限
- 默认内容在插槽没有被匹配时才生效
- 例子:
<template>
<div>
<header>
<!--定义一个叫header的插槽,传参data -->
<slot name="header" :data="data"></slot>
</header>
<div>MyComponent组件自己的内容1</div>
<!-- 这是默认插槽(也叫不具名插槽)-->
<!-- 等价于 <slot name="default" :middle="data.middle"></slot> -->
<slot :middle="data.middle"></slot>
<div>MyComponent组件自己的内容2</div>
<footer>
<!--定义一个叫footer的插槽,传参msg,bottom -->
<slot name="footer" :msg="data.footer" :bottom="data.bottom"></slot>
</footer>
</div>
</template>
<script>
export default {
name: "MyComponent",
data() {
return {
data: {
header: "header-slot",
middle: "default-slot",
footer: "footer-slot",
bottom: "bottom-slot",
}
}
}
}
</script>
3.插槽的使用
vue 2.6.0 中,我们为具名插槽和作用域插槽引入了一个新的统一的语法 (即 v-slot 指令)。它取代了 slot 和 slot-scope 这两个目前已被废弃但未被移除且仍在文档中的特性 —— vue官网
官方已经废弃了slot和slot-scope(但仍然可用),推荐使用v-slot,但是为了全面介绍插槽,两种写法此处都会介绍
为了便于描述,我称以下使用插槽的格式(格式1和格式2)为plug(插头),对应默认插槽的叫 默认plug
- 格式1(slot和slot-scope):
<template slot="插槽名称" slot-scope="scope">
<!-- 自定义内容 -->
</template>
- slot的值和插槽定义时的插槽名称对应,这样就可以替换对应的插槽部分,实现plug和插槽的匹配
- 如果是匹配默认插槽,slot可以省略,即<template slot-scope=“scope”>,或者slot的值可省略,即<template slot slot-scope=“scope”>,以下称它为“默认plug”
- 有多个plug的slot同名时(含默认plug),只有最后一个有效,前面的会失效(被丢弃)
- slot-scope用于接收参数,它的值是一个对象,可自定义名称,它包含了对应插槽定义时传入的所有参数,可通过scope.xxx, scope.yyy取值,支持解构写法,如:slot-scope=“{xxx, yyy}”
- plug的作用域为它位于的当前组件,它并不能访问对应插槽的作用域
- 请不要嵌套使用plug,因为它会导致作用域不明确
- 插槽匹配原则(简单总结,也适用于v-slot):
A. slot有值的情况下会通过名称匹配,匹配不到则丢弃;
B. slot没有值(或者名称为“default”)的情况下,会匹配默认插槽,默认插槽不存在则丢弃;
C. 只有在默认插槽存在且默认plug不存在的情况下,组件标签内多余的内容才会替换默认插槽的内容,否则会被丢弃;
D. 对于默认插槽,在默认plug不存在且组件标签内没有多余的内容情况下,其定义内的默认内容才会生效;对于具名插槽,对应的plug不存在则默认内容会生效
- 例子1:
<template>
<div>
<my-component>
<!-- 对接名称为"header"的插槽 -->
<template slot="header" slot-scope="scope">
<h1>{{scope.data.header}}</h1>
</template>
<!-- my-component中没有指定slot的部分会被全部放到默认插槽内(在默认plug不存在的情况下) -->
<p>default content A</p>
<p>and default content B</p>
<!-- 默认plug
<template slot-scope="scope">
<p>{{ scope.middle }}</p>
</template>
-->
<!-- 对接名称为"footer"的插槽 -->
<template slot="footer" slot-scope="scope">
<p>{{ scope.msg + "," + scope.bottom}}</p>
</template>
</my-component>
</div>
</template>
<script>
import MyComponent from './MyComponent.vue'
export default {
components: { MyComponent }
}
</script>
- 格式2(v-slot):
<template v-slot:插槽名称="scope">
<!-- 自定义内容 -->
</template>
- 如果是匹配默认插槽可以写成<template v-slot=“scope”>或者<template v-slot:default=“scope”>
- v-slot可简写为“#”,即<template #插槽名称=“scope”>,
但是对于默认插槽只能写成 #default=“scope” 不能写成 #=“scope”- 结合1和2,默认plug有三种写法:v-slot, v-slot:default,#default
- v-slot的值同slot-scope的值,可解构,即v-slot=“{ xxx, yyy }”
- v-slot只是格式1的不同写法,它的其他特性可参考格式1中的说明
- 例子2:
<template>
<div>
<my-component>
<!-- 对接名称为"header"的插槽 -->
<template v-slot:header="scope">
<h1>{{scope.data.header}}</h1>
</template>
<!-- 默认plug,对接默认插槽(不具名插槽)-->
<!-- 等价于<template #default="{ middle }"> -->
<template v-slot="{ middle }">
<p>{{ middle }}</p>
</template>
<!-- 在默认plug已存在的情况下,my-component中多余的内容会被丢弃 -->
<!-- 比如下面的内容没有匹配到任何的插槽,同时默认的插槽也被占用 -->
<!-- 所以下面的内容会被丢弃,这是插槽匹配中的一个重要特性-->
<p>default content.</p>
<!-- 对接名称为"footer"的插槽 -->
<template #footer="{ msg, bottom }">
<p>{{ msg + "," + bottom}}</p>
</template>
</my-component>
</div>
</template>
<script>
import MyComponent from './MyComponent.vue'
export default {
components: { MyComponent }
}
</script>
更多推荐
已为社区贡献1条内容
所有评论(0)