1.常规
slot是让一个组件预留插槽,用于扩展性设计。例如一个Window组件这么设计
<div class="window"><slot></slot></div>
那么使用者
<Window><span>xx</span></Window>
就等同于
<div class="window"><span>xx</span></div>
2.slot是有名字的
一个组件可以在不同的位置预留不同的插槽,那么使用的时候怎么区分插槽,这里就需要在设计和使用的时候都指明插槽的名字
例如一个Window组件这么设计:
<div class="window">
<div class="herder">
<slot name="header"></slot>
</div>
<div class="body">
<slot></slot>
</div>
<div class="footer">
<slot name="footer"></slot>
</div>
</div>
那么使用者
<Window>
<template #header>
<span>我在header</span>
</template>
<template #footer>
<span>我在footer</span>
</template>
<span>我在body</span>
</Window>
等同于
<div class="window">
<div class="herder">
<span>我在header</span>
</div>
<div class="body">
<span>我在footer</span>
</div>
<div class="footer">
<span>我在footer</span>
</div>
</div>
像前面的常规例子里面,没有名字的情况,其实也有名字的,名字叫default,也可以采用跟具名slot的写法一样使用,default的slot无需使用template包裹起来
3.slot可以把组件的参数传递给子组件
例如一个Window组件这么设计:
<div class="window"><slot :data1="data1" :data2="data2"></slot></div>
调用者:
<Window>
<template #default="{data1,data2}">
<span>xx{{data}},{{data2}}</span>
</template>
</Window>
这样在子组件就能访问到父组件的data1,data2的数据
4.我们希望调用者在传递了template的内容时使用template的内容,没有的时候使用其他默认内容
例如,我们一个Window组件,默认都是底部一个提交和取消按钮,但也可以扩展让调用者随便换别的内容,可以这么写
<div class="window">
<div class="footer">
<slot name="footer">
<button>提交</button>
<button>取消</button>
</slot>
</div>
</div>
slot包裹起来的内容就是默认内容,如果有子组件有使用temple名字是footer,就会覆盖slot的内容,即看不到提交和取消按钮
5.slot如何跨多个子组件传递
例如A组件有多个solt,B组件对A组件进行了封装,必然需要支持调用B组件的时候,能把solt的特性也支持,这个时候B组件就需要传递其调用者的slot
B组件的一个解决方案
const slots = useSlots();//获取所有slots
//在模板对应组件的位置遍历出来,v-slot等同#,指明slot的名字,也是遵顼slot的用法,套多一层
<template
v-for="(item, key, i) in slots"
:key="i"
v-slot:[key]="{ model, formitem }"
>
<slot :name="key" :model="model" :formitem="formitem"></slot>
</template>