优化
This commit is contained in:
@@ -1,21 +1,40 @@
|
||||
<script setup lang="ts">
|
||||
import { Comment, Fragment, Text, isVNode, useSlots } from 'vue'
|
||||
|
||||
withDefaults(defineProps<{
|
||||
ariaLabel?: string
|
||||
}>(), {
|
||||
ariaLabel: '列表页面',
|
||||
})
|
||||
|
||||
const slots = useSlots()
|
||||
type RegionName = 'toolbar' | 'metrics' | 'state' | 'default'
|
||||
|
||||
function hasRenderableContent(value: unknown): boolean {
|
||||
if (Array.isArray(value)) return value.some(hasRenderableContent)
|
||||
if (!isVNode(value)) return typeof value === 'string' ? value.trim().length > 0 : value != null && typeof value !== 'boolean'
|
||||
if (value.type === Comment) return false
|
||||
if (value.type === Text) return hasRenderableContent(value.children)
|
||||
if (value.type === Fragment) return hasRenderableContent(value.children)
|
||||
return true
|
||||
}
|
||||
|
||||
function hasRegion(name: RegionName) {
|
||||
return hasRenderableContent(slots[name]?.())
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section class="list-page-layout" :aria-label="ariaLabel">
|
||||
<div v-if="$slots.toolbar" class="list-page-layout__toolbar"><slot name="toolbar" /></div>
|
||||
<div v-if="$slots.metrics" class="list-page-layout__metrics"><slot name="metrics" /></div>
|
||||
<div v-if="$slots.state" class="list-page-layout__state"><slot name="state" /></div>
|
||||
<div v-if="$slots.default" class="list-page-layout__content"><slot /></div>
|
||||
<div v-if="hasRegion('toolbar')" class="list-page-layout__toolbar"><slot name="toolbar" /></div>
|
||||
<div v-if="hasRegion('metrics')" class="list-page-layout__metrics"><slot name="metrics" /></div>
|
||||
<div v-if="hasRegion('state')" class="list-page-layout__state"><slot name="state" /></div>
|
||||
<div v-if="hasRegion('default')" class="list-page-layout__content"><slot /></div>
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.list-page-layout { display: flex; min-width: 0; flex-direction: column; gap: 16px; }
|
||||
.list-page-layout__toolbar, .list-page-layout__metrics, .list-page-layout__state, .list-page-layout__content { min-width: 0; }
|
||||
.list-page-layout__toolbar:empty, .list-page-layout__metrics:empty, .list-page-layout__state:empty, .list-page-layout__content:empty { display: none; }
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user