Unverified Commit b8580bd1 authored by Sendya's avatar Sendya

fix: MenuUtil

parent 2b8873d9
......@@ -44,6 +44,10 @@ export interface BaseMenuProps extends Partial<PureSettings>, PrivateSiderMenuPr
// vue props
export const baseMenuProps = {
locale: Boolean,
prefixCls: {
type: String as PropType<string | undefined>,
default: () => 'ant-pro',
},
i18n: {
type: Function as PropType<FormatMessage>,
default: (t: string): string => t,
......@@ -76,70 +80,11 @@ export const baseMenuProps = {
},
};
const httpReg = /(http|https|ftp):\/\/([\w.]+\/?)\S*/;
const renderTitle = (title: string | undefined, i18nRender: FormatMessage) => {
return <span>{(i18nRender && title && i18nRender(title)) || title}</span>;
};
const renderMenuItem = (item: MenuDataItem, i18nRender: FormatMessage) => {
const meta = Object.assign({}, item.meta);
const target = meta.target || null;
const hasRemoteUrl = httpReg.test(item.path);
const CustomTag: any = resolveComponent((target && 'a') || 'router-link');
const props = { to: { name: item.name } };
const attrs = hasRemoteUrl || target ? { href: item.path, target: target } : {};
if (item.children && item.meta?.hideChildInMenu) {
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
// 都给子菜单增加一个 hidden 属性
// 用来给刷新页面时, selectedKeys 做控制用
item.children.forEach(cd => {
cd.meta = Object.assign(cd.meta || {}, { hidden: true });
});
}
// @ts-nocheck
return (
<Menu.Item key={item.path}>
<CustomTag {...attrs} {...props}>
<LazyIcon icon={meta.icon} />
{renderTitle(meta.title, i18nRender)}
</CustomTag>
</Menu.Item>
);
};
const renderSubMenu = (item: MenuDataItem, i18nRender: FormatMessage) => {
const renderMenuContent = (
<span>
<LazyIcon icon={item.meta?.icon} />
<span>{renderTitle(item.meta?.title, i18nRender)}</span>
</span>
) as string & VNode;
return (
<Menu.SubMenu key={item.path} title={renderMenuContent}>
{/* eslint-disable-next-line @typescript-eslint/no-use-before-define */}
{!item.meta?.hideChildInMenu && item.children.map(cd => renderMenu(cd, i18nRender))}
</Menu.SubMenu>
);
};
const renderMenu = (item: MenuDataItem, i18nRender: FormatMessage) => {
if (item && !item.meta.hidden) {
const hasChild = item.children && !item.meta?.hideChildInMenu;
return hasChild ? renderSubMenu(item, i18nRender) : renderMenuItem(item, i18nRender);
}
return null;
};
const IconFont = createFromIconfontCN({
scriptUrl: defaultSettings.iconfontUrl,
});
const LazyIcon = (props: {
icon: VNode | string;
iconPrefixes?: string;
prefixCls?: string;
}) => {
const LazyIcon = (props: { icon: VNode | string; iconPrefixes?: string; prefixCls?: string }) => {
const { icon, iconPrefixes = 'icon-', prefixCls = 'ant-pro' } = props;
if (!icon) {
return null;
......@@ -172,18 +117,17 @@ class MenuUtil {
constructor(props: BaseMenuProps) {
this.props = props;
console.log('MenuUtil constructor', new Date());
}
getNavMenuItems = (menusData: MenuDataItem[] = [], isChildren: boolean) => {
return menusData.map(item => this.getSubMenuOrItem(item, isChildren)).filter(item => item);
}
};
getSubMenuOrItem = (item: MenuDataItem, isChildren: boolean) => {
if (Array.isArray(item.children)
&& item.children.length > 0
&& !item?.meta?.hideInMenu) {
if (Array.isArray(item.children) && item.children.length > 0 && !item?.meta?.hideInMenu) {
const { prefixCls, i18n } = this.props;
const menuTitle = i18n && i18n(item.meta?.title) || item.meta?.title;
const menuTitle = (i18n && i18n(item.meta?.title)) || item.meta?.title;
const defaultTitle = item?.meta.icon ? (
<span class={`${prefixCls}-menu-item`}>
{!isChildren && <LazyIcon icon={item.meta.icon} />}
......@@ -210,7 +154,7 @@ class MenuUtil {
{this.getMenuItem(item, isChildren)}
</Menu.Item>
);
}
};
getMenuItem = (item: MenuDataItem, isChildren: boolean) => {
const meta = Object.assign({}, item.meta);
......@@ -221,7 +165,7 @@ class MenuUtil {
const attrs = hasUrl || target ? { href: item.path, target: target } : {};
const { prefixCls, i18n } = this.props;
const menuTitle = i18n && i18n(item.meta?.title) || item.meta?.title;
const menuTitle = (i18n && i18n(item.meta?.title)) || item.meta?.title;
const defaultTitle = item?.meta.icon ? (
<span class={`${prefixCls}-menu-item`}>
<CustomTag {...attrs} {...props}>
......@@ -234,7 +178,7 @@ class MenuUtil {
);
return defaultTitle;
}
};
conversionPath = (path: string) => {
if (path && path.indexOf('http') === 0) {
......@@ -249,8 +193,9 @@ export default defineComponent({
props: baseMenuProps,
emits: ['update:openKeys', 'update:selectedKeys'],
setup(props, { emit }) {
const { mode, i18n } = toRefs(props);
const { mode } = toRefs(props);
const isInline = computed(() => mode.value === 'inline');
const menuUtil = new MenuUtil(props);
const handleOpenChange: OpenEventHandler = (openKeys: string[]): void => {
emit('update:openKeys', openKeys);
......@@ -278,13 +223,7 @@ export default defineComponent({
onOpenChange={handleOpenChange}
onSelect={handleSelect}
>
{props.menuData &&
props.menuData.map(menu => {
if (menu.meta.hidden) {
return null;
}
return renderMenu(menu, i18n.value);
})}
{menuUtil.getNavMenuItems(props.menuData, false)}
</Menu>
);
},
......
......@@ -129,6 +129,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
}
const defaultMenuDom = (
<BaseMenu
prefixCls={getPrefixCls()}
theme={runtimeTheme.value === 'realDark' ? 'dark' : runtimeTheme.value}
mode="inline"
menuData={hasSide.value ? flatMenuData.value : context.menuData}
......
......@@ -85,6 +85,7 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = props => {
)}
<div style={{ flex: 1 }} class={`${prefixCls}-menu`}>
<BaseMenu
prefixCls={propPrefixCls}
theme={props.theme === 'realDark' ? 'dark' : props.theme}
mode={props.mode}
collapsed={props.collapsed}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment