Commit 5f70ec85 authored by Sendya's avatar Sendya

fix: render props check

parent 6e7be526
......@@ -101,8 +101,8 @@ const layoutConf = reactive({
| loading | layout loading status | boolean | - |
| layout | layout menu mode, sidemenu: right navigation, topmenu: top navigation | 'side' \| 'top' \| 'mix' | `'side'` |
| contentWidth | content mode of layout, Fluid: adaptive, Fixed: fixed width 1200px | 'Fixed' \| 'Fluid' | `Fluid` |
| theme | Navigation menu theme | 'light' \| 'dark' | `'light'` |
| navTheme | Navigation Bar theme | 'light' \|'dark' | `'light'` |
| navTheme | Navigation theme | 'light' \|'dark' | `'light'` |
| headerTheme | Header Bar theme | 'light' \|'dark' | `'light'` |
| menuData | Vue-router `routes` prop | Object | `[{}]` |
| collapsed | control menu's collapse and expansion | boolean | true |
| selectedKeys | menu selected keys | string[] | `[]` |
......
{
"name": "@ant-design-vue/pro-layout",
"version": "3.1.1",
"version": "3.1.2",
"license": "MIT",
"files": [
"dist"
......
import './index.less'
import './index.less';
import {
computed,
defineComponent,
onBeforeUnmount,
onMounted,
unref,
PropType,
} from 'vue'
import { RouteContextProps, useRouteContext } from '../RouteContext'
import { getPropsSlotfn } from '../utils'
import type { CustomRender } from '../typings'
import { computed, defineComponent, onBeforeUnmount, onMounted, unref, PropType } from 'vue';
import { RouteContextProps, useRouteContext } from '../RouteContext';
import { getPropsSlotfn } from '../utils';
import type { CustomRender } from '../typings';
export interface FooterToolbarProps {
extra?: CustomRender | JSX.Element
extra?: CustomRender | JSX.Element;
renderContent?: (
props: FooterToolbarProps & RouteContextProps & { leftWidth?: string },
dom: CustomRender | JSX.Element
) => CustomRender | JSX.Element
getContainer?: (triggerNode: HTMLElement) => HTMLElement | null
prefixCls?: string
dom: CustomRender | JSX.Element,
) => CustomRender | JSX.Element;
getContainer?: (triggerNode: HTMLElement) => HTMLElement | null;
prefixCls?: string;
}
const footerToolbarProps = {
extra: {
type: Object as PropType<FooterToolbarProps['extra']>,
type: [Function, Object, Boolean] as PropType<FooterToolbarProps['extra']>,
},
renderContent: {
type: [Function, Object] as PropType<FooterToolbarProps['renderContent']>,
type: [Function, Object, Boolean] as PropType<FooterToolbarProps['renderContent']>,
},
getContainer: {
type: [Function, Object] as PropType<FooterToolbarProps['getContainer']>,
},
prefixCls: { type: String as PropType<string> },
}
};
const FooterToolbar = defineComponent({
name: 'FooterToolbar',
props: footerToolbarProps,
setup(props, { slots }) {
const context = useRouteContext()
const baseClassName = props.prefixCls || context.getPrefixCls('footer-bar')
const context = useRouteContext();
const baseClassName = props.prefixCls || context.getPrefixCls('footer-bar');
const hasFlatMenu = computed(() => {
return unref(context.flatMenuData).length > 0
})
return unref(context.flatMenuData).length > 0;
});
const width = computed(() => {
const { isMobile, hasSide, siderWidth, layout } = context
const { isMobile, hasSide, siderWidth, layout } = context;
if (!siderWidth || layout === 'top') {
return '100%'
return '100%';
}
console.log(
'x',
......@@ -55,24 +48,24 @@ const FooterToolbar = defineComponent({
'hasFlatMenu',
unref(hasFlatMenu),
'hasSide',
unref(context.hasSide)
)
unref(context.hasSide),
);
if (!hasFlatMenu.value && !unref(hasSide)) {
return '100%'
return '100%';
}
console.log('x2', unref(context.hasSide))
return isMobile ? '100%' : `calc(100% - ${siderWidth}px)`
})
console.log('x2', unref(context.hasSide));
return isMobile ? '100%' : `calc(100% - ${siderWidth}px)`;
});
onMounted(() => {
context.setHasFooterToolbar && context.setHasFooterToolbar(true)
})
context.setHasFooterToolbar && context.setHasFooterToolbar(true);
});
onBeforeUnmount(() => {
context.setHasFooterToolbar && context.setHasFooterToolbar(false)
})
context.setHasFooterToolbar && context.setHasFooterToolbar(false);
});
return () => {
const extra = getPropsSlotfn(slots, props, 'extra')
const extra = getPropsSlotfn(slots, props, 'extra');
const dom = () => {
return (
<>
......@@ -81,8 +74,8 @@ const FooterToolbar = defineComponent({
</div>
<div class={`${baseClassName}-right`}>{slots.default?.()}</div>
</>
)
}
);
};
return (
<div class={baseClassName} style={{ width: width.value }}>
{props.renderContent
......@@ -92,13 +85,13 @@ const FooterToolbar = defineComponent({
...context,
leftWidth: width.value,
},
dom()
dom(),
)
: dom()}
</div>
)
}
);
};
},
})
});
export default FooterToolbar
export default FooterToolbar;
......@@ -21,7 +21,7 @@ export default {
},
splitMenus: siderMenuProps.splitMenus,
menuRender: {
type: [Object, Function] as PropType<
type: [Object, Function, Boolean] as PropType<
WithFalse<(props: any /* HeaderViewProps */, defaultDom: CustomRender) => CustomRender>
>,
default: () => undefined,
......@@ -30,7 +30,7 @@ export default {
menuItemRender: siderMenuProps.menuItemRender,
subMenuItemRender: siderMenuProps.subMenuItemRender,
rightContentRender: {
type: [Object, Function] as PropType<WithFalse<(props: any) => CustomRender>>,
type: [Object, Function, Boolean] as PropType<WithFalse<(props: any) => CustomRender>>,
default: () => undefined,
},
collapsedButtonRender: siderMenuProps.collapsedButtonRender,
......
......@@ -18,19 +18,19 @@ const { Header } = Layout;
export const headerViewProps = {
...globalHeaderProps,
headerRender: {
type: [Object, Function] as PropType<
type: [Object, Function, Boolean] as PropType<
WithFalse<(props: any, defaultDom: CustomRender) => CustomRender>
>,
default: () => undefined,
},
headerTitleRender: {
type: [Object, Function] as PropType<
type: [Object, Function, Boolean] as PropType<
WithFalse<(props: any, defaultDom: CustomRender) => CustomRender>
>,
default: () => undefined,
},
headerContentRender: {
type: [Object, Function] as PropType<WithFalse<(props: any) => CustomRender>>,
type: [Object, Function, Boolean] as PropType<WithFalse<(props: any) => CustomRender>>,
default: () => undefined,
},
hasSiderMenu: PropTypes.looseBool,
......
......@@ -12,7 +12,7 @@ import {
import omit from 'omit.js';
import { withInstall } from 'ant-design-vue/es/_util/type';
import PageHeader, { pageHeaderProps } from 'ant-design-vue/es/page-header';
import { Tabs, Affix, Spin, } from 'ant-design-vue';
import { Tabs, Affix, Spin } from 'ant-design-vue';
import { TabPaneProps } from './interfaces/TabPane';
import { TabBarExtraContent, TabsProps } from './interfaces/Tabs';
import { AffixProps } from './interfaces/Affix';
......@@ -50,7 +50,7 @@ export const pageHeaderTabConfig = {
* @name tab 上多余的区域
*/
tabBarExtraContent: {
type: [Object, Function] as PropType<TabBarExtraContent>,
type: [Object, Function, Boolean] as PropType<TabBarExtraContent>,
default: () => undefined,
},
/**
......@@ -206,9 +206,9 @@ const defaultPageHeaderRender = (
if (!title && title !== false) {
pageHeaderTitle = value.title;
}
const unrefBreadcrumb = unref(value.breadcrumb || {})
const unrefBreadcrumb = unref(value.breadcrumb || {});
const breadcrumb = restProps.breadcrumb || {
...(unrefBreadcrumb),
...unrefBreadcrumb,
routes: unrefBreadcrumb.routes,
itemRender: unrefBreadcrumb.itemRender,
};
......
......@@ -5,24 +5,24 @@ import {
PropType,
CSSProperties,
unref,
} from 'vue'
import 'ant-design-vue/es/layout/style'
import 'ant-design-vue/es/menu/style'
import { Layout, Menu } from 'ant-design-vue'
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'
import BaseMenu, { baseMenuProps } from './BaseMenu'
import { WithFalse, CustomRender } from '../typings'
import { SiderProps } from './typings'
import { defaultSettingProps } from '../defaultSettings'
import { useRouteContext } from '../RouteContext'
import { PropTypes, getMenuFirstChildren } from '../utils'
import './index.less'
} from 'vue';
import 'ant-design-vue/es/layout/style';
import 'ant-design-vue/es/menu/style';
import { Layout, Menu } from 'ant-design-vue';
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import BaseMenu, { baseMenuProps } from './BaseMenu';
import { WithFalse, CustomRender } from '../typings';
import { SiderProps } from './typings';
import { defaultSettingProps } from '../defaultSettings';
import { useRouteContext } from '../RouteContext';
import { PropTypes, getMenuFirstChildren } from '../utils';
import './index.less';
const { Sider } = Layout
const { Sider } = Layout;
export type PrivateSiderMenuProps = {
matchMenuKeys?: string[]
}
matchMenuKeys?: string[];
};
export const siderMenuProps = {
...defaultSettingProps,
......@@ -39,35 +39,27 @@ export const siderMenuProps = {
headerHeight: PropTypes.number.def(48),
collapsedWidth: PropTypes.number.def(48),
menuHeaderRender: {
type: [Function, Object] as PropType<
WithFalse<
(logo: CustomRender, title: CustomRender, props?: any) => CustomRender
>
type: [Function, Object, Boolean] as PropType<
WithFalse<(logo: CustomRender, title: CustomRender, props?: any) => CustomRender>
>,
default: () => undefined,
},
menuFooterRender: {
type: [Function, Object] as PropType<
WithFalse<(props?: any) => CustomRender>
>,
type: [Function, Object, Boolean] as PropType<WithFalse<(props?: any) => CustomRender>>,
default: () => undefined,
},
menuContentRender: {
type: [Function, Object] as PropType<
type: [Function, Object, Boolean] as PropType<
WithFalse<(props: any, defaultDom: CustomRender) => CustomRender>
>,
default: () => undefined,
},
menuExtraRender: {
type: [Function, Object] as PropType<
WithFalse<(props?: any) => CustomRender>
>,
type: [Function, Object, Boolean] as PropType<WithFalse<(props?: any) => CustomRender>>,
default: () => undefined,
},
collapsedButtonRender: {
type: [Function, Object, Boolean] as PropType<
WithFalse<(collapsed?: boolean) => CustomRender>
>,
type: [Function, Object, Boolean] as PropType<WithFalse<(collapsed?: boolean) => CustomRender>>,
default: () => undefined,
},
breakpoint: {
......@@ -95,52 +87,49 @@ export const siderMenuProps = {
onSelect: {
type: Function as PropType<(selectedKeys: WithFalse<string[]>) => void>,
},
}
};
export type SiderMenuProps = Partial<ExtractPropTypes<typeof siderMenuProps>>
export type SiderMenuProps = Partial<ExtractPropTypes<typeof siderMenuProps>>;
export const defaultRenderLogo = (
logo?: CustomRender,
logoStyle?: CSSProperties
): CustomRender => {
export const defaultRenderLogo = (logo?: CustomRender, logoStyle?: CSSProperties): CustomRender => {
if (!logo) {
return null
return null;
}
if (typeof logo === 'string') {
return <img src={logo} alt="logo" style={logoStyle} />
return <img src={logo} alt="logo" style={logoStyle} />;
}
if (typeof logo === 'function') {
return logo()
return logo();
}
return logo
}
return logo;
};
export const defaultRenderLogoAndTitle = (
props: SiderMenuProps,
renderKey: string | undefined = 'menuHeaderRender'
renderKey: string | undefined = 'menuHeaderRender',
): CustomRender | null => {
const {
logo = 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg',
logoStyle,
title,
layout,
} = props
const renderFunction = (props as any)[renderKey || '']
} = props;
const renderFunction = (props as any)[renderKey || ''];
if (renderFunction === false) {
return null
return null;
}
const logoDom = defaultRenderLogo(logo, logoStyle)
const titleDom = <h1>{title}</h1>
const logoDom = defaultRenderLogo(logo, logoStyle);
const titleDom = <h1>{title}</h1>;
if (layout === 'mix' && renderKey === 'menuHeaderRender') {
return null
return null;
}
// call menuHeaderRender
if (typeof renderFunction === 'function') {
// when collapsed, no render title
return renderFunction(logoDom, props.collapsed ? null : titleDom, props)
return renderFunction(logoDom, props.collapsed ? null : titleDom, props);
}
if (Array.isArray(renderFunction)) {
return <>{renderFunction}</>
return <>{renderFunction}</>;
}
return (
......@@ -148,12 +137,11 @@ export const defaultRenderLogoAndTitle = (
{logoDom}
{props.collapsed ? null : titleDom}
</a>
)
}
);
};
export const defaultRenderCollapsedButton = (
collapsed?: boolean
): CustomRender => (collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />)
export const defaultRenderCollapsedButton = (collapsed?: boolean): CustomRender =>
collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />;
const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
const {
......@@ -170,42 +158,36 @@ const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
onOpenKeys,
onSelect,
onMenuHeaderClick,
} = props
const context = useRouteContext()
const { getPrefixCls } = context
const baseClassName = getPrefixCls('sider')
const hasSplitMenu = computed(
() => props.layout === 'mix' && props.splitMenus
)
const sTheme = computed(
() => (props.layout === 'mix' && 'light') || props.navTheme
)
const sSideWidth = computed(() =>
props.collapsed ? props.collapsedWidth : props.siderWidth
)
} = props;
const context = useRouteContext();
const { getPrefixCls } = context;
const baseClassName = getPrefixCls('sider');
const hasSplitMenu = computed(() => props.layout === 'mix' && props.splitMenus);
const sTheme = computed(() => (props.layout === 'mix' && 'light') || props.navTheme);
const sSideWidth = computed(() => (props.collapsed ? props.collapsedWidth : props.siderWidth));
const classNames = computed(() => {
return {
[baseClassName]: true,
[`${baseClassName}-${sTheme.value}`]: true,
[`${baseClassName}-${props.layout}`]: true,
[`${baseClassName}-fixed`]: context.fixSiderbar,
}
})
};
});
const handleSelect = ($event: string[]) => {
if (props.onSelect) {
if (unref(hasSplitMenu)) {
props.onSelect([context.selectedKeys[0], ...$event])
return
props.onSelect([context.selectedKeys[0], ...$event]);
return;
}
props.onSelect($event)
props.onSelect($event);
}
}
};
// call menuHeaderRender
const headerDom = defaultRenderLogoAndTitle(props)
const extraDom = menuExtraRender && menuExtraRender(props)
const headerDom = defaultRenderLogoAndTitle(props);
const extraDom = menuExtraRender && menuExtraRender(props);
if (hasSplitMenu.value && unref(context.flatMenuData).length === 0) {
return null
return null;
}
const defaultMenuDom = (
<BaseMenu
......@@ -226,12 +208,11 @@ const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
}}
class={`${baseClassName}-menu`}
{...{
'onUpdate:openKeys': ($event: string[]) =>
onOpenKeys && onOpenKeys($event),
'onUpdate:openKeys': ($event: string[]) => onOpenKeys && onOpenKeys($event),
'onUpdate:selectedKeys': handleSelect,
}}
/>
)
);
return (
<>
......@@ -253,16 +234,14 @@ const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
collapsed={collapsed}
breakpoint={breakpoint || undefined}
onCollapse={(collapse: boolean) => {
if (props.isMobile) return
onCollapse?.(collapse)
if (props.isMobile) return;
onCollapse?.(collapse);
}}
collapsedWidth={collapsedWidth}
style={{
overflow: 'hidden',
paddingTop:
props.layout === 'mix' && !props.isMobile
? `${props.headerHeight}px`
: undefined,
props.layout === 'mix' && !props.isMobile ? `${props.headerHeight}px` : undefined,
}}
width={siderWidth}
theme={sTheme.value === 'realDark' ? 'dark' : sTheme.value}
......@@ -289,8 +268,7 @@ const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
</div>
)}
<div style="flex: 1; overflow: hidden auto;">
{(menuContentRender && menuContentRender(props, defaultMenuDom)) ||
defaultMenuDom}
{(menuContentRender && menuContentRender(props, defaultMenuDom)) || defaultMenuDom}
</div>
<div class={`${baseClassName}-links`}>
{collapsedButtonRender !== false ? (
......@@ -304,7 +282,7 @@ const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
// @ts-ignore
onClick={() => {
if (onCollapse) {
onCollapse(!props.collapsed)
onCollapse(!props.collapsed);
}
}}
>
......@@ -313,20 +291,17 @@ const SiderMenu: FC<SiderMenuProps> = (props: SiderMenuProps) => {
class={`${baseClassName}-collapsed-button`}
title={false}
>
{collapsedButtonRender &&
typeof collapsedButtonRender === 'function'
{collapsedButtonRender && typeof collapsedButtonRender === 'function'
? collapsedButtonRender(collapsed)
: collapsedButtonRender}
</Menu.Item>
</Menu>
) : null}
</div>
{menuFooterRender && (
<div class={`${baseClassName}-footer`}>{menuFooterRender(props)}</div>
)}
{menuFooterRender && <div class={`${baseClassName}-footer`}>{menuFooterRender(props)}</div>}
</Sider>
</>
)
}
);
};
export default SiderMenu
export default SiderMenu;
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