slot插槽
开发中,很多地方会遇见slot,经常用到,却没有认证整理过。实为可耻。今天特意看了一些文章。整理slot的功能如下。
官方文档是这样解释slot的作用的:
元素作为组件模板之中的内容分发插槽。 元素自身将被替换。
1、element-ui的dialog
举个最常见的“栗子”,el-dialog的源码中是这样写的。
<template>
<transition
name="dialog-fade"
@after-enter="afterEnter"
@after-leave="afterLeave">
<div
v-show="visible"
class="el-dialog__wrapper"
@click.self="handleWrapperClick">
<div
role="dialog"
:key="key"
aria-modal="true"
:aria-label="title || 'dialog'"
:class="['el-dialog', { 'is-fullscreen': fullscreen, 'el-dialog--center': center }, customClass]"
ref="dialog"
:style="style">
<div class="el-dialog__header">
<slot name="title">
<span class="el-dialog__title">{{ title }}</span>
</slot> // slot插槽
<button
type="button"
class="el-dialog__headerbtn"
aria-label="Close"
v-if="showClose"
@click="handleClose">
<i class="el-dialog__close el-icon el-icon-close"></i>
</button>
</div>
<div class="el-dialog__body" v-if="rendered"><slot></slot></div> // 默认的slot插槽
<div class="el-dialog__footer" v-if="$slots.footer">
<slot name="footer"></slot> // slot插槽
</div>
</div>
</div>
</transition>
</template>
我们可以看到el-dialog实际上提供饿了3个插槽,footer上面的不具名的插槽,是一个默认的插槽,会作为body内容自动插入。我们在开发中最常用的应该就是这个footer插槽。
然后查看el-dialog中slot的用法
从这个组件的用法,我们不难看出,slot的作用,在于你调用组件时候,可以将你自定义的dom、方法、属性等自动插入到slot名字定义的位置,因此叫做“具名插槽”。大家管这种方式,通俗的叫做“占坑”,是的,你可以那样理解。
2、作用域插槽
我们看到slot的“占坑”作用非常方便开发中使用。其实slot还有其他作用,那就是作用域传值。
当我们在父组件中需要使用,直接使用v-slot(以前是slot-scope,在2.6版本已经弃用,现在都用v-slot)获取子组件的数据即可。
子组件:
<template>
<div class="son-component">
<slot :userInfo="userInfo" :hobby="hobby"></slot>
<p>上面是插槽</p>
</div>
</template>
<script>
export default {
data() {
return {
userInfo: {
name: '张飞',
age: 230
},
hobby: {
first: 'sing',
second: 'paint'
}
}
},
}
</script>
父组件
在父组件中用v-slot接收参数
<son-component>
<template v-slot="scope">
<pre>
{{scope}}
</pre>
<p>姓名:{{scope.userInfo.name}}</p>
</template>
</son-component>
我们查看打印出来的页面:
不难发现scope对象,包括含了,slot插槽上传的所有数据,使用的时候直接用对象的打点调用就好了。
总结:
作用域插槽就是将子组件的数据和方法传给父组件。
3、无渲染组件
什么是无渲染组件?
是指一个不需要html元素,不去渲染自己的html,而是只提供属性和方法的组件。
在什么使用场景下?
在某些场景下,我们需要渲染多个子组件,但是我们只需要子组件的属性和方法。子组件的样式有很大的区别。此时,我们就需要用到无渲染组件。
一个无渲染组件,通过render函数去暴露一个作用域插槽,并提供属性和方法。
render() {
return this.$scopedSlots.default({
currentState: this.dataString,
operateA: this.operateA,
operateB: this.operateB,
operateC: this.operateC,
})
}
这样在父组件中我们可以通过 v-slot="{dataString, operateA, operateB, operateC}" 获取到子组件的属性方法,然后自定义不一样的html来渲染不同的子组件。
bingo,任务完成!是不是很好用。
无渲染组件,在组件封装、二开的时候非常有用。
我的语雀地址:[www.yuque.com/docs/share/… 《slot插槽》](www.yuque.com/docs/share/… 《slot插槽》)