在setup
中使用插槽,需要配合render
渲染函数,先上代码。
子组件slotsTest.vue
:
<script lang="ts">
import { h,renderSlot,Slots,reactive } from "vue";
interface SetupContext {
slots:Slots
}
interface Data {
[key:string]:unknown
}
interface listData {
id:number,
text:string
}
export default {
setup(props:Data,{slots}:SetupContext){
const list = reactive<listData[]>([
{
id:1,
text:"hahaha"
},
{
id:2,
text:"hehehe"
},
{
id:3,
text:"kokokoko"
},
])
return ()=>[
h("div",{className:'default_class'},[renderSlot(slots,'default')]),
h("div",{className:'header_class'},[renderSlot(slots,'header')]),
list.map(item=>{
return h("p",{className:'p_class'},[renderSlot(slots,'list',{item})])
})
]
}
}
</script>
<style lang="scss">
.default_class {
font-size: 20px;
color: aqua;
}
.header_class {
font-size: 20px;
color: green;
font-weight: 700;
}
.p_class {
font-size: 12px;
color: red;
font-weight: 700;
}
</style>
从vue引入renderSlot,Slots作为插槽的渲染函数和类型:
import { h,renderSlot,Slots,reactive } from "vue";
renderSlot
的第一个参数,就是从父组件传入的插槽内容;第二个参数则是具名插槽的名字,在父组件可以指定,下文会介绍;第三个参数则是从子组件传给父组件的props
,经常用在循环的内容里,供父组件获取循环的元素值。
h("div",{className:'default_class'},[renderSlot(slots,'default')]),
h("div",{className:'header_class'},[renderSlot(slots,'header')]),
list.map(item=>{
return h("p",{className:'p_class'},[renderSlot(slots,'list',{item:item})])
})
下边来看父组件怎么使用。
父组件index.vue
:
<script lang="ts">
import SlotsTest from './slotsTest.vue'
export default {
components:{SlotsTest}
}
<template>
<div>
<SlotsTest>
<p>hello world</p>
<template #header>这是头部</template>
<template #list="props">
<span>{{props.item.id}}</span>
=>
<span>{{props.item.text}}</span>
</template>
</SlotsTest>
</div>
</template>
父组件引用子组件时,组件标签内的默认内容对应的是:
[renderSlot(slots,'default')]
具名tamplate
:<template #header>
则对应的是:
[renderSlot(slots,'header')]
同理 <template #list="props">
对应的是:
[renderSlot(slots,'list',{item})
而props
的值就是{item}
对象。
注意:#header是v-slot:header的另一种写法,必须用在template标签里。
打开浏览器查看渲染情况:
有帮助的话,点个关注呗!