Skip to content

Instantly share code, notes, and snippets.

@lisonge
Last active November 18, 2025 08:59
Show Gist options
  • Select an option

  • Save lisonge/dd96dc2e786a8de1d952c5dde2dde020 to your computer and use it in GitHub Desktop.

Select an option

Save lisonge/dd96dc2e786a8de1d952c5dde2dde020 to your computer and use it in GitHub Desktop.
import type { SlotsType, VNode } from 'vue'
import { Comment, Fragment } from 'vue'
const isEmpty = (nodes: VNode[] | undefined): boolean => {
if (!nodes?.length) return true
return nodes.every((v) => {
return (
v.type === Comment ||
(v.type === Fragment && isEmpty(v.children as VNode[])) ||
// @ts-ignore
(v.type === NotEmpty && isEmpty(v.children?.default?.()))
)
})
}
/**
* 仅在有子节点时渲染内容的容器组件
*/
const NotEmpty = defineComponent<
object,
Record<string, never>,
string,
SlotsType<{
prefix: () => VNode[]
default: () => VNode[]
suffix: () => VNode[]
}>
>((props, ctx) => {
return () => {
const children = ctx.slots.default?.()
if (isEmpty(children)) {
return h(Comment, 'NotEmpty')
}
return h('div', props, [ctx.slots.prefix?.(), children, ctx.slots.suffix?.()].filter(Boolean))
}
})
export default NotEmpty
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment