vue3 h函数中如何使用插槽
前言
vue3已经出了有一段时间了,越来越多的小伙伴开始用vue3来写项目。开发过程中难免会用到h函数, 有时候会使用h函数封装一些组件,封装组件又会用到插槽。所以呢对于在h函数中如何使用插槽稍作了整理,希望能帮到帮接触h函数的小伙伴。
这里只讲解插槽的用法,不涉及h函数如何使用,如需了解h函数用法,可查阅官网文档-渲染函数
什么是h函数
h()
是 hyperscript 的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。一个更准确的名称应该是
createVnode()
,但当你需要多次使用渲染函数时,一个简短的名字会更省力。
使用插槽
插槽使用方式这里可分为两种,下面一一介绍。
第一种方式 (使用slots.xxxxx?.())
- 默认插槽这里是一个子组件A.ts
import{ h, defineComponent }from'vue'exportdefaultdefineComponent({setup(_,{ slots }){return()=>h('span', slots.default?.())}})
- 具名插槽这里是一个子组件B.ts
import{ h, defineComponent }from'vue'exportdefaultdefineComponent({setup(_,{ slots }){return()=>h('span', slots.foo?.())}})``````这个foo就是具名插槽的名字
- 作用域插槽这里是一个子组件C.ts
import{ h, defineComponent }from'vue'exportdefaultdefineComponent({setup(_,{ slots }){return()=>h('span', slots.footer?.({msg:'这是一条来自作用域插槽(C组件)传递的数据',list:['a','b','c','d']}))}})``````{ msg: '这是一条来自作用域插槽(C组件)传递的数据', list: ['a', 'b', 'c', 'd'] } 这个对象就是向外部传递的数据
- 在父组件中使用这是父组件Content.ts
import{ h, defineComponent }from'vue'importAfrom'./A'importBfrom'./B'importCfrom'./C'exportdefaultdefineComponent({setup(){return()=>h('div',[h(A,()=>h('div','我是默认插槽')),// 注意 `null` 是必需的// 以避免 slot 对象被当成 prop 处理h(B,null,{foo:()=>h('div','我是具名插槽')}),// 注意 `null` 是必需的// 以避免 slot 对象被当成 prop 处理h(C,null,{// 通过解构得到插槽作用域的参数footer:({ msg, list }:{msg: string,list: string[]})=>[h('h2','我是作用域插槽'),h('div',`msg: ${msg}`),h('div',`list: 接收到了作用域插槽(C组件的List)---> ${list}`),]}),])}})
第二种方式 (使用renderSlot)
- 默认插槽这里是一个子组件A.ts
import{ renderSlot, h, defineComponent }from'vue'exportdefaultdefineComponent({setup(_,{ slots }){return()=>h('div',renderSlot(slots,'default'))}})
- 具名插槽这里是一个子组件B.ts
import{ renderSlot, h, defineComponent }from'vue'exportdefaultdefineComponent({setup(_,{ slots }){return()=>h('div',renderSlot(slots,'foo'))}})``````这个foo就是具名插槽的名字
- 作用域插槽这里是一个子组件C.ts
import{ renderSlot, h, defineComponent }from'vue'exportdefaultdefineComponent({setup(_,{ slots }){return()=>h('div',renderSlot(slots,'footer',{msg:'这是一条来自作用域插槽(C组件)传递的数据',list:['a','b','c','d']}))}})
{ msg: '这是一条来自作用域插槽(C组件)传递的数据', list: ['a', 'b', 'c', 'd'] } 这个对象就是向外部传递的数据
- 父组件中使用这是父组件Content.ts
import{ h, defineComponent }from'vue'importAfrom'./A'importBfrom'./B'importCfrom'./C'exportdefaultdefineComponent({setup(){return()=>h('div',[h(A,()=>h('div','我是默认插槽')),// 注意 `null` 是必需的// 以避免 slot 对象被当成 prop 处理h(B,null,{foo:()=>h('div','我是具名插槽')}),// 注意 `null` 是必需的// 以避免 slot 对象被当成 prop 处理h(C,null,{// 通过解构得到插槽作用域的参数footer:({ msg, list }:{msg: string,list: string[]})=>[h('h2','我是作用域插槽'),h('div',`msg: ${msg}`),h('div',`list: 接收到了作用域插槽(C组件的List)---> ${list}`),]}),])}})
> 两种方式区别不大,就是一个使用renderSlot, 一个使用slots.xxxxx?.()的方式。
其他
如果想了解Tsx中如何使用插槽可参考Tsx中使用插槽
版权归原作者 zhfy啊 所有, 如有侵权,请联系我们删除。