njzscloud-dispose-web/src/pages/a-frame/AAside.tsx

110 lines
2.7 KiB
TypeScript

import {
ElButton,
ElIcon,
ElMenu,
ElMenuItem,
ElMenuItemGroup,
ElSubMenu,
type MenuItemRegistered,
} from 'element-plus'
import { elIcons } from '@/common/element/element.ts'
export interface Menu extends G.TreeNode {
// Id
id: string
// 编码
sn: string
// 上级 Id; 层级为 1 的节点值为 0
pid: string
// 菜单名称
title: string
// 图标
icon: string
// 层级; >= 1
tier: number
// 排序
sort: number
// 路由名称
routeName: string
// 面包路径
breadcrumb: string[]
// 类型
menuCategory: 'Catalog' | 'Group' | 'Page' | 'SubPage' | 'Btn'
// 子菜单
children?: Menu[]
}
export default defineComponent(
({menus}, {emit}) => {
const onMenuClick = (it: MenuItemRegistered) => emit('menuClick', it.index)
const renderMenu = (it: Menu) => {
let renderChildNode: (() => VNode[] | undefined) | undefined = undefined
if (it.children != null && it.children.length > 0) {
renderChildNode = () => (it.children?.map(renderMenu))
}
let currentNode: VNode
switch (it.menuCategory) {
case 'Catalog': {
currentNode = (<ElSubMenu index={it.id}>
{{
title: () => <span>{it.title}</span>,
default: renderChildNode,
}}
</ElSubMenu>)
break
}
case 'Group': {
currentNode = (<ElMenuItemGroup title={it.title}>
{{
default: renderChildNode,
}}
</ElMenuItemGroup>)
break
}
case 'Page': {
currentNode = (<ElMenuItem index={it.id} onClick={onMenuClick}>
{{
default: () => <span>{it.title}</span>,
}}
</ElMenuItem>)
break
}
default:
currentNode = (<></>)
}
return currentNode
}
const isCollapse = ref(false)
return () => (<>
<ElMenu collapse={isCollapse.value} style={{height: '100%', overflow: 'auto', '--el-menu-base-level-padding': '10px'}} class={'menus'}>
{{
default: () => menus.map(renderMenu),
}}
</ElMenu>
<ElButton style={{position: 'absolute', right: 0, bottom: 0, width: '32px', height: '32px'}} onClick={() => {
isCollapse.value = !isCollapse.value
}}>
<ElIcon style={{cursor: 'pointer'}}>
{
isCollapse.value ? <elIcons.Fold/> : <elIcons.Expand/>
}
</ElIcon>
</ElButton>
</>)
},
{
props: {
menus: {
type: Object as PropType<Menu[]>,
required: true,
validator: (value: Menu[]) => value != null && value.length > 0,
},
},
emits: {
menuClick: (id: string) => id != null,
},
name: 'AAside',
})