以下内容适用于vue 2.6.0及以后的版本
插槽作用
Vue 实现了一套内容分发的 API,这套 API 的设计灵感源自 Web Components 规范草案,将 slot 元素作为承载分发内容的出口。
插槽分类
Vue里的插槽大概可以分为三类,分别是匿名插槽,具名插槽以及作用域插槽。
插槽介绍
子组件
<div>
<p>
<slot name="header">我是header后备内容</slot>
</p>
<p>
<slot>我是content后备内容</slot>
</p>
<p>
<slot name="footer">我是footer后备内容</slot>
</p>
</div>
父组件
<template v-slot:header>header</template>
<template v-slot:default>content</template>
<template v-slot:footer>footer</template>
如上所示,在vue2.6版本后,具名插槽的使用方式是:首先在子组件中给slot添加name属性,然后在父组件的template中利用v-slot指令并制定name值,就会将父组件中该template的内容渲染到子组件对应的slot中。
渲染结果
注1
- 同其它指令一样,v-slot指令也有自己的语法糖,可以将v-slot替换为#,但#后必须指定name属性值,如果是匿名插槽,则为#default。
- 内容分发的时候最好使用template包裹起来,如果子组件中有匿名插槽,并且父组件中未指定匿名插槽的内容,则默认将所有内容添加到匿名插槽下。
- 后备内容指的是在父组件中未指定插槽内容时,子组件显示的内容。
作用域插槽
有时让插槽内容能够访问子组件中才有的数据是很有用的,作用域插槽可以向父组件传递子组件中的插槽数据,从而父组件可以根据插槽中的数据对插槽的内容进行修改。
子组件
<p>
<slot :test="msg">我是content后备内容</slot>
</p>
data() {
return {
msg: '我是插槽想要传递回来的信息'
}
}
父组件
<template #default='slotProps'>
<h3>{{ slotProps.test }}</h3>
<ul>
<li v-for='i in 5' :key='i'>这是第{{ i }}条新闻</li>
</ul>
</template>
渲染结果
注2
- 自定义属性可以随意书写,只不过在获取属性时要相互对应;slotProps也可以修改,但为了语义化以及书写习惯,最好不要修改。
- 因为v-slot:default=提供了一个js环境,可以利用解构赋值来更方便的获取该属性值,以及修改属性名和设置默认值。 如父组件:
<template #default='{ test: childMsg }'>
<h3>{{ childMsg }}</h3>
<ul>
<li v-for='i in 5' :key='i'>这是第{{ i }}条新闻</li>
</ul>
</template>
实际场景&原理
有待补充