Commit 2b556487 authored by Sendya's avatar Sendya

fix: layout test

parent 8a8fc81d
...@@ -11,12 +11,18 @@ module.exports = { ...@@ -11,12 +11,18 @@ module.exports = {
'@vue/prettier/@typescript-eslint', '@vue/prettier/@typescript-eslint',
], ],
parserOptions: { parserOptions: {
// ecmaVersion: 2020, ecmaVersion: 2020,
parser: '@typescript-eslint/parser', // parser: '@typescript-eslint/parser',
}, },
rules: { rules: {
'@typescript-eslint/no-explicit-any': 0, '@typescript-eslint/no-explicit-any': 0,
'@typescript-eslint/no-inferrable-types': 0, '@typescript-eslint/no-inferrable-types': 0,
'@typescript-eslint/ban-ts-ignore': 'off',
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-empty-function': 'off',
'@typescript-eslint/no-non-null-assertion': 'off',
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
}, },
......
{ {
"singleQuote": true, "singleQuote": true,
"trailingComma": "all", "trailingComma": "all",
"endOfLine" : "lf",
"printWidth": 100, "printWidth": 100,
"proseWrap": "never", "proseWrap": "never",
"arrowParens": "avoid",
"htmlWhitespaceSensitivity": "ignore",
"overrides": [ "overrides": [
{ {
"files": ".prettierrc", "files": ".prettierrc",
......
...@@ -6,7 +6,6 @@ import { default as ProLayout } from '../src/'; ...@@ -6,7 +6,6 @@ import { default as ProLayout } from '../src/';
import { menus } from './menus'; import { menus } from './menus';
import * as Icon from '@ant-design/icons-vue'; import * as Icon from '@ant-design/icons-vue';
import { createRouteContext, RouteContextProps } from '../src/RouteContext'; import { createRouteContext, RouteContextProps } from '../src/RouteContext';
import { DemoBox } from './demoBox';
const BasicLayout = defineComponent({ const BasicLayout = defineComponent({
name: 'BasicLayout', name: 'BasicLayout',
...@@ -29,20 +28,24 @@ const BasicLayout = defineComponent({ ...@@ -29,20 +28,24 @@ const BasicLayout = defineComponent({
hasHeader: true, hasHeader: true,
hasFooterToolbar: false, hasFooterToolbar: false,
setHasFooterToolbar: (has: boolean) => (state.hasFooterToolbar = has), setHasFooterToolbar: (has: boolean) => (state.hasFooterToolbar = has),
}) });
const [ RouteContextProvider ] = createRouteContext(); const [RouteContextProvider] = createRouteContext();
const cacheOpenKeys = ref<string[]>([]); const cacheOpenKeys = ref<string[]>([]);
watch( watch(
() => state.collapsed, () => state.collapsed,
(collapsed: boolean) => { (collapsed: boolean) => {
console.log('post watch', collapsed, state.collapsed);
if (collapsed) { if (collapsed) {
cacheOpenKeys.value = state.openKeys; cacheOpenKeys.value = state.openKeys;
state.openKeys = []; state.openKeys = [];
} else { } else {
state.openKeys = cacheOpenKeys.value; state.openKeys = cacheOpenKeys.value;
} }
} },
{
flush: 'pre',
},
); );
return () => ( return () => (
...@@ -63,15 +66,15 @@ const BasicLayout = defineComponent({ ...@@ -63,15 +66,15 @@ const BasicLayout = defineComponent({
v-slots={{ v-slots={{
rightContentRender: () => ( rightContentRender: () => (
<div style="color: #FFF;margin-right: 16px;"> <div style="color: #FFF;margin-right: 16px;">
<Avatar icon={(<Icon.UserOutlined />)} /> Sendya <Avatar icon={<Icon.UserOutlined />} /> Sendya
</div> </div>
), ),
menuHeaderRender: () => ( menuHeaderRender: () => (
<a> <a>
<img src="https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg" /> <img src="https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg" />
{state.collapsed ? null : (<h1>Pro Layout</h1>)} {state.collapsed ? null : <h1>Pro Layout</h1>}
</a> </a>
) ),
}} }}
> >
<Button <Button
......
...@@ -28,42 +28,42 @@ ...@@ -28,42 +28,42 @@
}, },
"devDependencies": { "devDependencies": {
"@ant-design-vue/tools": "^3.0.4", "@ant-design-vue/tools": "^3.0.4",
"@babel/core": "^7.12.9", "@babel/core": "^7.12.10",
"@babel/plugin-proposal-export-default-from": "^7.12.1", "@babel/plugin-proposal-export-default-from": "^7.12.1",
"@babel/plugin-transform-modules-commonjs": "^7.12.1", "@babel/plugin-transform-modules-commonjs": "^7.12.1",
"@babel/plugin-transform-object-assign": "^7.12.1", "@babel/plugin-transform-object-assign": "^7.12.1",
"@babel/preset-env": "^7.12.7", "@babel/preset-env": "^7.12.11",
"@types/fs-extra": "^9.0.2", "@types/fs-extra": "^9.0.6",
"@types/jest": "^24.0.17", "@types/jest": "^24.0.17",
"@types/node": "^13.13.15", "@types/node": "^13.13.15",
"@types/rimraf": "^3.0.0", "@types/rimraf": "^3.0.0",
"@typescript-eslint/eslint-plugin": "^2.33.0", "@typescript-eslint/eslint-plugin": "^2.33.0",
"@typescript-eslint/parser": "^2.33.0", "@typescript-eslint/parser": "^2.33.0",
"@vue/babel-plugin-jsx": "^1.0.0-rc.3", "@vue/babel-plugin-jsx": "^1.0.0-rc.5",
"@vue/cli-plugin-babel": "~4.5.0", "@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0", "@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0", "@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-service": "~4.5.0", "@vue/cli-service": "~4.5.0",
"@vue/compiler-sfc": "^3.0.0-0", "@vue/compiler-sfc": "^3.0.3",
"@vue/eslint-config-prettier": "^6.0.0", "@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2", "@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^2.0.0-beta.2", "@vue/test-utils": "^2.0.0-beta.2",
"babel-jest": "^26.6.3", "babel-jest": "^26.6.3",
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
"cross-env": "^5.2.0", "cross-env": "^7.0.3",
"eslint": "^6.7.2", "eslint": "^7.16.0",
"eslint-config-prettier": "^6.15.0", "eslint-config-prettier": "^7.1.0",
"eslint-plugin-prettier": "^3.1.3", "eslint-plugin-prettier": "^3.3.0",
"eslint-plugin-vue": "^7.0.0-0", "eslint-plugin-vue": "^7.3.0",
"fs-extra": "^9.0.1", "fs-extra": "^9.0.1",
"jest": "^26.6.3", "jest": "^26.6.3",
"jest-environment-jsdom-fifteen": "^1.0.2", "jest-environment-jsdom-fifteen": "^1.0.2",
"jest-serializer-vue": "^2.0.2", "jest-serializer-vue": "^2.0.2",
"jest-transform-stub": "^2.0.0", "jest-transform-stub": "^2.0.0",
"prettier": "^1.19.1", "prettier": "^2.2.1",
"rimraf": "^3.0.2", "rimraf": "^3.0.2",
"ts-jest": "^26.4.4", "ts-jest": "^26.4.4",
"ts-node": "^8.10.2", "ts-node": "^9.1.1",
"typescript": "~3.9.3", "typescript": "~3.9.3",
"vue": "^3.0.0-0", "vue": "^3.0.0-0",
"vue-jest": "^5.0.0-alpha.3", "vue-jest": "^5.0.0-alpha.3",
...@@ -71,8 +71,8 @@ ...@@ -71,8 +71,8 @@
}, },
"dependencies": { "dependencies": {
"@babel/runtime": "^7.11.2", "@babel/runtime": "^7.11.2",
"ant-design-vue": "^2.0.0-beta.10", "ant-design-vue": "^2.0.0-rc.5",
"lodash-es": "^4.17.15", "lodash-es": "^4.17.20",
"vue-types": "^3.0.1" "vue-types": "^3.0.1"
}, },
"config": { "config": {
......
...@@ -3,7 +3,6 @@ import 'ant-design-vue/es/layout/style'; ...@@ -3,7 +3,6 @@ import 'ant-design-vue/es/layout/style';
import Layout from 'ant-design-vue/es/layout'; import Layout from 'ant-design-vue/es/layout';
import { withInstall } from 'ant-design-vue/es/_util/type'; import { withInstall } from 'ant-design-vue/es/_util/type';
import { default as ProProvider, ProProviderData } from './ProProvider'; import { default as ProProvider, ProProviderData } from './ProProvider';
import { default as GlobalFooter } from './GlobalFooter';
import { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu'; import { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu';
import { WrapContent } from './WrapContent'; import { WrapContent } from './WrapContent';
import { default as Header, HeaderViewProps } from './Header'; import { default as Header, HeaderViewProps } from './Header';
...@@ -14,41 +13,42 @@ import './BasicLayout.less'; ...@@ -14,41 +13,42 @@ import './BasicLayout.less';
const defaultI18nRender = (key: string) => key; const defaultI18nRender = (key: string) => key;
export type BasicLayoutProps = SiderMenuWrapperProps & HeaderViewProps & { export type BasicLayoutProps = SiderMenuWrapperProps &
pure?: boolean; HeaderViewProps & {
/** pure?: boolean;
*@name logo url /**
*/ *@name logo url
logo?: string | RenderVNodeType | WithFalse<string | RenderVNodeType>; */
logo?: string | RenderVNodeType | WithFalse<string | RenderVNodeType>;
loading?: boolean; loading?: boolean;
i18n?: ProProviderData['i18n']; i18n?: ProProviderData['i18n'];
defaultCollapsed?: boolean; defaultCollapsed?: boolean;
onCollapse?: (collapsed: boolean) => void; onCollapse?: (collapsed: boolean) => void;
footerRender?: WithFalse< footerRender?: WithFalse<
(props: any /* FooterProps */, defaultDom: RenderVNodeType) => RenderVNodeType (props: any /* FooterProps */, defaultDom: RenderVNodeType) => RenderVNodeType
>; >;
headerRender?: WithFalse<(props: any /* HeaderProps */) => RenderVNodeType>; headerRender?: WithFalse<(props: any /* HeaderProps */) => RenderVNodeType>;
colSize?: string; colSize?: string;
/** /**
* 是否禁用移动端模式,有的管理系统不需要移动端模式,此属性设置为true即可 * 是否禁用移动端模式,有的管理系统不需要移动端模式,此属性设置为true即可
*/ */
disableMobile?: boolean; disableMobile?: boolean;
isChildrenLayout?: boolean; isChildrenLayout?: boolean;
contentStyle?: CSSProperties; contentStyle?: CSSProperties;
/** /**
* 兼用 content的 margin * 兼用 content的 margin
*/ */
disableContentMargin?: boolean; disableContentMargin?: boolean;
}; };
const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots, attrs }) => { const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots, attrs }) => {
const { const {
...@@ -102,28 +102,31 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots, ...@@ -102,28 +102,31 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots,
customHeaderRender: VNodeChild | false; customHeaderRender: VNodeChild | false;
rightContentRender: VNodeChild | false; rightContentRender: VNodeChild | false;
}, },
matchMenuKeys: string[] matchMenuKeys: string[],
): RenderVNodeType => { ): RenderVNodeType => {
if (props.headerRender === false || props.pure) { if (props.headerRender === false || props.pure) {
return null; return null;
} }
return <Header matchMenuKeys={matchMenuKeys} {...props} headerHeight={48} />; return <Header matchMenuKeys={matchMenuKeys} {...props} headerHeight={48} />;
} };
const rightContentRender = getComponentOrSlot(props, slots, 'rightContentRender'); const rightContentRender = getComponentOrSlot(props, slots, 'rightContentRender');
const customHeaderRender = getComponentOrSlot(props, slots, 'headerRender');; const customHeaderRender = getComponentOrSlot(props, slots, 'headerRender');
const headerDom = headerRender({ const headerDom = headerRender(
...props, {
hasSiderMenu: isTop.value, ...props,
menuData, hasSiderMenu: isTop.value,
isMobile, menuData,
collapsed, isMobile,
onCollapse, collapsed,
onSelect: handleSelect, onCollapse,
onOpenChange: handleOpenChange, onSelect: handleSelect,
customHeaderRender, onOpenChange: handleOpenChange,
rightContentRender, customHeaderRender,
theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light', rightContentRender,
}, matchMenuKeys); theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light',
},
matchMenuKeys,
);
const footerRender = getComponentOrSlot(props, slots, 'footerRender'); const footerRender = getComponentOrSlot(props, slots, 'footerRender');
const menuRender = getComponentOrSlot(props, slots, 'menuRender'); const menuRender = getComponentOrSlot(props, slots, 'menuRender');
...@@ -133,26 +136,28 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots, ...@@ -133,26 +136,28 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots,
return ( return (
<ProProvider i18n={defaultI18nRender}> <ProProvider i18n={defaultI18nRender}>
{ props.pure {props.pure ? (
? (slots.default?.()) slots.default?.()
: ( ) : (
<div class={className.value}> <div class={className.value}>
<Layout class={baseClassName.value}> <Layout class={baseClassName.value}>
{ !isTop.value && (<SiderMenuWrapper {!isTop.value && (
<SiderMenuWrapper
{...props} {...props}
menuHeaderRender={menuHeaderRenderFunc || (menuHeaderRenderSlot && (() => menuHeaderRenderSlot()))} menuHeaderRender={
menuHeaderRenderFunc || (menuHeaderRenderSlot && (() => menuHeaderRenderSlot()))
}
onCollapse={handleCollapse} onCollapse={handleCollapse}
/>)} />
<Layout> )}
{headerDom} <Layout>
<WrapContent style={props.contentStyle}> {headerDom}
{slots.default?.()} <WrapContent style={props.contentStyle}>{slots.default?.()}</WrapContent>
</WrapContent> {footerRender !== false && footerRender && footerRender}
{ footerRender !== false && (footerRender && footerRender)}
</Layout>
</Layout> </Layout>
</div> </Layout>
)} </div>
)}
</ProProvider> </ProProvider>
); );
}; };
......
import { computed, CSSProperties, FunctionalComponent, toRefs } from 'vue'; import { computed, CSSProperties, FunctionalComponent } from 'vue';
import { PureSettings } from '../defaultSettings'; import { PureSettings } from '../defaultSettings';
import { RenderVNodeType, MenuDataItem, WithFalse } from '../typings'; import { RenderVNodeType, MenuDataItem, WithFalse } from '../typings';
import { SiderMenuProps, PrivateSiderMenuProps, defaultRenderLogo, defaultRenderLogoAndTitle, defaultRenderCollapsedButton } from '../SiderMenu/SiderMenu'; import {
SiderMenuProps,
PrivateSiderMenuProps,
defaultRenderLogo,
defaultRenderLogoAndTitle,
defaultRenderCollapsedButton,
} from '../SiderMenu/SiderMenu';
import { TopNavHeader } from '../TopNavHeader'; import { TopNavHeader } from '../TopNavHeader';
import { clearMenuItem } from '../utils'; import { clearMenuItem } from '../utils';
import type { HeaderViewProps } from '../Header'; import type { HeaderViewProps } from '../Header';
...@@ -23,7 +29,7 @@ export interface GlobalHeaderProps extends Partial<PureSettings> { ...@@ -23,7 +29,7 @@ export interface GlobalHeaderProps extends Partial<PureSettings> {
menuHeaderRender?: SiderMenuProps['menuHeaderRender']; menuHeaderRender?: SiderMenuProps['menuHeaderRender'];
collapsedButtonRender?: SiderMenuProps['collapsedButtonRender']; collapsedButtonRender?: SiderMenuProps['collapsedButtonRender'];
splitMenus?: boolean; splitMenus?: boolean;
}; }
const renderLogo = ( const renderLogo = (
menuHeaderRender: SiderMenuProps['menuHeaderRender'], menuHeaderRender: SiderMenuProps['menuHeaderRender'],
...@@ -38,7 +44,10 @@ const renderLogo = ( ...@@ -38,7 +44,10 @@ const renderLogo = (
return logoDom; return logoDom;
}; };
export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderMenuProps> = (props, { slots }) => { export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderMenuProps> = (
props,
{ slots },
) => {
const { const {
isMobile, isMobile,
logo, logo,
...@@ -48,7 +57,7 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM ...@@ -48,7 +57,7 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM
rightContentRender, rightContentRender,
menuHeaderRender, menuHeaderRender,
onMenuHeaderClick, onMenuHeaderClick,
className: propClassName, // className: propClassName,
layout, layout,
headerTheme = 'dark', headerTheme = 'dark',
splitMenus, splitMenus,
...@@ -62,10 +71,10 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM ...@@ -62,10 +71,10 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM
return { return {
[baseClassName.value]: true, [baseClassName.value]: true,
[`${baseClassName.value}-layout-${layout}`]: layout && headerTheme === 'dark', [`${baseClassName.value}-layout-${layout}`]: layout && headerTheme === 'dark',
} };
}); });
if (layout === 'mix' && !isMobile && splitMenus) { if (layout === 'mix' && !isMobile && splitMenus) {
const noChildrenMenuData = (menuData || []).map((item) => ({ const noChildrenMenuData = (menuData || []).map(item => ({
...item, ...item,
children: undefined, children: undefined,
})); }));
...@@ -110,12 +119,11 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM ...@@ -110,12 +119,11 @@ export const GlobalHeader: FunctionalComponent<GlobalHeaderProps & PrivateSiderM
</> </>
)} )}
<div style={{ flex: 1 }}>{slots.default?.()}</div> <div style={{ flex: 1 }}>{slots.default?.()}</div>
{ rightContentRender && typeof rightContentRender === 'function' {rightContentRender && typeof rightContentRender === 'function'
? rightContentRender(props) ? rightContentRender(props)
: rightContentRender : rightContentRender}
}
</div> </div>
); );
} };
export default GlobalHeader; export default GlobalHeader;
import { FunctionalComponent, CSSProperties, toRefs } from 'vue'; import { FunctionalComponent, CSSProperties } from 'vue';
import { useProProvider } from '../ProProvider'; import { useProProvider } from '../ProProvider';
import { PureSettings } from '../defaultSettings'; import { PureSettings } from '../defaultSettings';
import './GridContent.less'; import './GridContent.less';
......
import { defineComponent, computed, toRefs, toRaw } from 'vue'; import { defineComponent, computed, toRefs } from 'vue';
import 'ant-design-vue/es/layout/style'; import 'ant-design-vue/es/layout/style';
import Layout from 'ant-design-vue/es/layout'; import Layout from 'ant-design-vue/es/layout';
...@@ -55,24 +55,37 @@ export const headerProps = [ ...@@ -55,24 +55,37 @@ export const headerProps = [
'navTheme', 'navTheme',
'onSelect', 'onSelect',
'onOpenChange', 'onOpenChange',
] ];
export const HeaderView = defineComponent({ export const HeaderView = defineComponent({
inheritAttrs: false, inheritAttrs: false,
name: 'HeaderView', name: 'HeaderView',
props: headerProps, props: headerProps,
setup(props: HeaderViewProps) { setup(props: HeaderViewProps) {
const { prefixCls, headerRender, headerContentRender, isMobile, fixedHeader, hasSiderMenu, headerHeight, layout, navTheme, onCollapse } = toRefs(props); const {
console.log('HeaderView', props) prefixCls,
headerRender,
headerContentRender,
isMobile,
fixedHeader,
hasSiderMenu,
headerHeight,
layout,
navTheme,
onCollapse,
} = toRefs(props);
console.log('HeaderView', props);
const isTop = computed(() => props.layout === 'top'); const isTop = computed(() => props.layout === 'top');
const needFixedHeader = computed(() => fixedHeader.value || layout.value === 'mix'); const needFixedHeader = computed(() => fixedHeader.value || layout.value === 'mix');
const needSettingWidth = computed(() => needFixedHeader.value && hasSiderMenu.value && !isTop.value && !isMobile.value); const needSettingWidth = computed(
() => needFixedHeader.value && hasSiderMenu.value && !isTop.value && !isMobile.value,
);
const clearMenuData = computed(() => clearMenuItem(props.menuData || [])); const clearMenuData = computed(() => clearMenuItem(props.menuData || []));
const className = computed(() => { const className = computed(() => {
return { return {
[`${prefixCls.value}-fixed-header`]: needFixedHeader.value, [`${prefixCls.value}-fixed-header`]: needFixedHeader.value,
[`${prefixCls.value}-top-menu`]: isTop.value, [`${prefixCls.value}-top-menu`]: isTop.value,
} };
}); });
const renderContent = () => { const renderContent = () => {
let defaultDom = ( let defaultDom = (
...@@ -95,7 +108,7 @@ export const HeaderView = defineComponent({ ...@@ -95,7 +108,7 @@ export const HeaderView = defineComponent({
return headerRender.value(props, defaultDom); return headerRender.value(props, defaultDom);
} }
return defaultDom; return defaultDom;
} };
/** /**
* 计算侧边栏的宽度,不然导致左边的样式会出问题 * 计算侧边栏的宽度,不然导致左边的样式会出问题
...@@ -103,9 +116,9 @@ export const HeaderView = defineComponent({ ...@@ -103,9 +116,9 @@ export const HeaderView = defineComponent({
const width = computed(() => { const width = computed(() => {
return layout.value !== 'mix' && needSettingWidth.value return layout.value !== 'mix' && needSettingWidth.value
? `calc(100% - ${props.collapsed ? 48 : props.siderWidth}px)` ? `calc(100% - ${props.collapsed ? 48 : props.siderWidth}px)`
: '100%'; : '100%';
}); });
const right = computed(() => needFixedHeader.value ? 0 : undefined); const right = computed(() => (needFixedHeader.value ? 0 : undefined));
return () => ( return () => (
<> <>
{needFixedHeader.value && ( {needFixedHeader.value && (
......
...@@ -65,7 +65,7 @@ const ProProvider = defineComponent({ ...@@ -65,7 +65,7 @@ const ProProvider = defineComponent({
}, },
}); });
ProProvider.install = function(app: App) { ProProvider.install = function (app: App) {
app.component(ProProvider.name, ProProvider); app.component(ProProvider.name, ProProvider);
}; };
......
...@@ -14,10 +14,18 @@ export interface BreadcrumbProps { ...@@ -14,10 +14,18 @@ export interface BreadcrumbProps {
routes?: Route[]; routes?: Route[];
params?: any; params?: any;
separator?: VNodeChild; separator?: VNodeChild;
itemRender?: (route: Route, params: any, routes: Array<Route>, paths: Array<string>) => VNodeChild; itemRender?: (
route: Route,
params: any,
routes: Array<Route>,
paths: Array<string>,
) => VNodeChild;
} }
export type BreadcrumbListReturn = Pick<BreadcrumbProps, Extract<keyof BreadcrumbProps, 'routes' | 'itemRender'>>; export type BreadcrumbListReturn = Pick<
BreadcrumbProps,
Extract<keyof BreadcrumbProps, 'routes' | 'itemRender'>
>;
export interface MenuState { export interface MenuState {
selectedKeys: string[]; selectedKeys: string[];
...@@ -44,8 +52,6 @@ export interface RouteContextProps extends Partial<PureSettings>, MenuState { ...@@ -44,8 +52,6 @@ export interface RouteContextProps extends Partial<PureSettings>, MenuState {
const routeContextInjectKey: InjectionKey<RouteContextProps> = Symbol(); const routeContextInjectKey: InjectionKey<RouteContextProps> = Symbol();
export const createRouteContext = () => export const createRouteContext = () => createContext<RouteContextProps>(routeContextInjectKey);
createContext<RouteContextProps>(routeContextInjectKey);
export const useRouteContext = () => export const useRouteContext = () => useContext<RouteContextProps>(routeContextInjectKey);
useContext<RouteContextProps>(routeContextInjectKey);
...@@ -11,14 +11,13 @@ import { ...@@ -11,14 +11,13 @@ import {
} from 'vue'; } from 'vue';
import { createFromIconfontCN } from '@ant-design/icons-vue'; import { createFromIconfontCN } from '@ant-design/icons-vue';
import 'ant-design-vue/es/menu/style'; import 'ant-design-vue/es/menu/style';
import Menu, { MenuProps } from 'ant-design-vue/es/menu'; import Menu from 'ant-design-vue/es/menu';
import defaultSettings, { PureSettings } from '../defaultSettings'; import defaultSettings, { PureSettings } from '../defaultSettings';
import { isImg, isUrl } from '../utils'; import { isImg, isUrl } from '../utils';
import { MenuMode, SelectInfo, OpenEventHandler } from './typings'; import { MenuMode, SelectInfo, OpenEventHandler } from './typings';
import { MenuDataItem, MenuTheme, FormatMessage, WithFalse } from '../typings'; import { MenuDataItem, MenuTheme, FormatMessage, WithFalse } from '../typings';
import { PrivateSiderMenuProps } from './SiderMenu'; import { PrivateSiderMenuProps } from './SiderMenu';
import './index.less'; import './index.less';
import { useMenuState } from '../hooks/useMenu';
export { MenuMode, SelectInfo, OpenEventHandler }; export { MenuMode, SelectInfo, OpenEventHandler };
...@@ -78,10 +77,10 @@ const renderTitle = (title: string | undefined, i18nRender: FormatMessage) => { ...@@ -78,10 +77,10 @@ const renderTitle = (title: string | undefined, i18nRender: FormatMessage) => {
const renderMenuItem = (item: MenuDataItem, i18nRender: FormatMessage) => { const renderMenuItem = (item: MenuDataItem, i18nRender: FormatMessage) => {
const meta = Object.assign({}, item.meta); const meta = Object.assign({}, item.meta);
const target = meta.target || null; const target = meta.target || null;
const hasRemoteUrl = httpReg.test(item.path) const hasRemoteUrl = httpReg.test(item.path);
const CustomTag: any = resolveComponent((target && 'a') || 'router-link'); const CustomTag: any = resolveComponent((target && 'a') || 'router-link');
const props = { to: { name: item.name } }; const props = { to: { name: item.name } };
const attrs = (hasRemoteUrl || target) ? { href: item.path, target: target } : {}; const attrs = hasRemoteUrl || target ? { href: item.path, target: target } : {};
if (item.children && item.meta?.hideChildInMenu) { if (item.children && item.meta?.hideChildInMenu) {
// 把有子菜单的 并且 父菜单是要隐藏子菜单的 // 把有子菜单的 并且 父菜单是要隐藏子菜单的
// 都给子菜单增加一个 hidden 属性 // 都给子菜单增加一个 hidden 属性
......
import { FunctionalComponent, computed, ref } from 'vue'; import { FunctionalComponent, computed } from 'vue';
import 'ant-design-vue/es/layout/style'; import 'ant-design-vue/es/layout/style';
import Layout from 'ant-design-vue/es/layout'; import Layout from 'ant-design-vue/es/layout';
import 'ant-design-vue/es/menu/style'; import 'ant-design-vue/es/menu/style';
...@@ -114,7 +114,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -114,7 +114,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
[`${baseClassName}-${navTheme}`]: true, [`${baseClassName}-${navTheme}`]: true,
[`${baseClassName}-${props.layout}`]: true, [`${baseClassName}-${props.layout}`]: true,
[`${baseClassName}-fixed`]: context.fixSiderbar, [`${baseClassName}-fixed`]: context.fixSiderbar,
} };
}); });
// call menuHeaderRender // call menuHeaderRender
const headerDom = defaultRenderLogoAndTitle(props); const headerDom = defaultRenderLogoAndTitle(props);
......
...@@ -7,7 +7,7 @@ import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu'; ...@@ -7,7 +7,7 @@ import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu';
export type SiderMenuWrapperProps = SiderMenuProps & Partial<PrivateSiderMenuProps>; export type SiderMenuWrapperProps = SiderMenuProps & Partial<PrivateSiderMenuProps>;
const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = (props, { attrs }) => { const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = props => {
return props.isMobile ? ( return props.isMobile ? (
<Drawer> <Drawer>
<SiderMenu {...props} /> <SiderMenu {...props} />
......
import { ref, computed, FunctionalComponent } from "vue"; import { ref, computed, FunctionalComponent } from 'vue';
import { import {
SiderMenuProps, SiderMenuProps,
defaultRenderLogoAndTitle, defaultRenderLogoAndTitle,
...@@ -9,7 +9,7 @@ import { GlobalHeaderProps } from '../GlobalHeader'; ...@@ -9,7 +9,7 @@ import { GlobalHeaderProps } from '../GlobalHeader';
import { default as ResizeObserver } from 'ant-design-vue/es/vc-resize-observer'; import { default as ResizeObserver } from 'ant-design-vue/es/vc-resize-observer';
import './index.less'; import './index.less';
import { useRouteContext } from "../RouteContext"; import { useRouteContext } from '../RouteContext';
export type TopNavHeaderProps = SiderMenuProps & GlobalHeaderProps & PrivateSiderMenuProps & {}; export type TopNavHeaderProps = SiderMenuProps & GlobalHeaderProps & PrivateSiderMenuProps & {};
...@@ -38,14 +38,16 @@ const RightContent: FunctionalComponent<TopNavHeaderProps> = ({ rightContentRend ...@@ -38,14 +38,16 @@ const RightContent: FunctionalComponent<TopNavHeaderProps> = ({ rightContentRend
...props, ...props,
})} })}
</div> </div>
) : rightContentRender} ) : (
rightContentRender
)}
</ResizeObserver> </ResizeObserver>
</div> </div>
</div> </div>
); );
}; };
export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { emit }) => { export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = props => {
const headerRef = ref(); const headerRef = ref();
const { const {
prefixCls: propPrefixCls, prefixCls: propPrefixCls,
...@@ -53,7 +55,6 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { em ...@@ -53,7 +55,6 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { em
contentWidth, contentWidth,
rightContentRender, rightContentRender,
layout, layout,
...restProps
} = props; } = props;
const context = useRouteContext(); const context = useRouteContext();
const prefixCls = `${propPrefixCls || 'ant-pro'}-top-nav-header`; const prefixCls = `${propPrefixCls || 'ant-pro'}-top-nav-header`;
...@@ -65,39 +66,39 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { em ...@@ -65,39 +66,39 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = (props, { em
return { return {
[prefixCls]: true, [prefixCls]: true,
light: props.theme === 'light', light: props.theme === 'light',
} };
}); });
return ( return (
<div class={className.value}> <div class={className.value}>
<div ref={headerRef} class={`${prefixCls}-main ${contentWidth === 'Fixed' ? 'wide' : ''}`}> <div ref={headerRef} class={`${prefixCls}-main ${contentWidth === 'Fixed' ? 'wide' : ''}`}>
{headerDom && ( {headerDom && (
<div class={`${prefixCls}-main-left`} onClick={onMenuHeaderClick}> <div class={`${prefixCls}-main-left`} onClick={onMenuHeaderClick}>
<div class={`${prefixCls}-logo`} key="logo" id="logo"> <div class={`${prefixCls}-logo`} key="logo" id="logo">
{headerDom} {headerDom}
</div>
</div> </div>
)}
<div style={{ flex: 1 }} class={`${prefixCls}-menu`}>
<BaseMenu
theme={props.theme === 'realDark' ? 'dark' : props.theme}
mode={props.mode}
collapsed={props.collapsed}
menuData={context.menuData}
openKeys={context.openKeys}
selectedKeys={context.selectedKeys}
class={{ 'top-nav-menu': props.mode === 'horizontal' }}
{...{
'onUpdate:openKeys': ($event: string[]) => {
context.onOpenKeys($event);
},
'onUpdate:selectedKeys': ($event: any) => {
context.onSelectedKeys($event);
},
}}
/>
</div> </div>
)} {rightContentRender && <RightContent rightContentRender={rightContentRender} {...props} />}
<div style={{ flex: 1 }} class={`${prefixCls}-menu`}>
<BaseMenu
theme={props.theme === 'realDark' ? 'dark' : props.theme}
mode={props.mode}
collapsed={props.collapsed}
menuData={context.menuData}
openKeys={context.openKeys}
selectedKeys={context.selectedKeys}
class={{ 'top-nav-menu': props.mode === 'horizontal' }}
{...{
'onUpdate:openKeys': ($event: string[]) => {
context.onOpenKeys($event);
},
'onUpdate:selectedKeys': ($event: any) => {
context.onSelectedKeys($event);
},
}}
/>
</div> </div>
{rightContentRender && <RightContent rightContentRender={rightContentRender} {...props} />}
</div> </div>
</div> );
)
}; };
...@@ -22,8 +22,8 @@ export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slot ...@@ -22,8 +22,8 @@ export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slot
return { return {
[`${prefixCls}-content`]: true, [`${prefixCls}-content`]: true,
[`${prefixCls}-has-header`]: true, [`${prefixCls}-has-header`]: true,
} };
}) });
return ( return (
<Content class={classNames.value} {...attrs}> <Content class={classNames.value} {...attrs}>
......
...@@ -16,12 +16,9 @@ export { ...@@ -16,12 +16,9 @@ export {
default as BaseMenu, default as BaseMenu,
BaseMenuProps, BaseMenuProps,
MenuMode, MenuMode,
MenuState,
MenuStateWatched,
OpenEventHandler, OpenEventHandler,
SelectInfo, SelectInfo,
VueBaseMenuProps, VueBaseMenuProps,
useMenuState,
} from './SiderMenu/BaseMenu'; } from './SiderMenu/BaseMenu';
export { default } from './BasicLayout'; export { default } from './BasicLayout';
This diff is 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