vue3 slot 插槽 在h函数中如何使用
h()是的简称——意思是“能生成 HTML (超文本标记语言) 的 JavaScript”。这个名字来源于许多虚拟 DOM 实现默认形成的约定。一个更准确的名称应该是,但当你需要多次使用渲染函数时,一个简短的名字会更省力。
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' export default defineComponent({ setup(_, { slots }) { return () => h('span', slots.default?.()) } })
-
具名插槽
这里是一个子组件B.ts
import { h, defineComponent } from 'vue' export default defineComponent({ setup(_, { slots }) { return () => h('span', slots.foo?.()) } })
这个foo就是具名插槽的名字
-
作用域插槽
这里是一个子组件C.ts
import { h, defineComponent } from 'vue' export default defineComponent({ 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' import A from './A' import B from './B' import C from './C' export default defineComponent({ 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' export default defineComponent({ setup(_, { slots }) { return () => h('div', renderSlot(slots, 'default')) } })
-
具名插槽
这里是一个子组件B.ts
import { renderSlot, h, defineComponent } from 'vue' export default defineComponent({ setup(_, { slots }) { return () => h('div', renderSlot(slots, 'foo')) } })
这个foo就是具名插槽的名字
-
作用域插槽
这里是一个子组件C.ts
import { renderSlot, h, defineComponent } from 'vue' export default defineComponent({ 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' import A from './A' import B from './B' import C from './C' export default defineComponent({ 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中使用插槽
更多推荐
所有评论(0)