Commit c6c2a115 authored by Sendya's avatar Sendya

fix: FooterToolbar auto margin

parent 0f46541a
......@@ -224,8 +224,14 @@ const layoutConf = reactive({
</template>
```
### Use WaterMark
```vue
<router-view v-slot="{ Component }">
<WaterMark content="Pro Layout">
<component :is="Component" />
</WaterMark>
</router-view>
```
## Build project
......
......@@ -6,7 +6,7 @@
v-bind="state"
:loading="loading"
:breadcrumb="{ routes: breadcrumb }"
iconfont-url="//at.alicdn.com/t/font_2804900_26tw52dc2pl.js"
iconfont-url="//at.alicdn.com/t/font_2804900_nzigh7z84gc.js"
>
<template #menuHeaderRender>
<a>
......@@ -39,7 +39,7 @@
</router-link>
</template>
<template #menuExtraRender="{ collapsed }">
<a-input-search v-if="!collapsed" />
<a-input-search v-if="!collapsed" @search="handleSearch" />
</template>
<template #menuFooterRender>
<a
......@@ -67,26 +67,13 @@
</a>
</template>
<!-- custom menu-item -->
<template #menuItemRender="{ item, icon }">
<a-menu-item
:key="item.path"
:disabled="item.meta?.disabled"
:danger="item.meta?.danger"
:icon="icon"
>
<router-link :to="{ path: item.path }">
<span class="ant-pro-menu-item">
<a-badge count="5" dot>
<span class="ant-pro-menu-item-title">{{ item.meta.title }}</span>
</a-badge>
</span>
</router-link>
</a-menu-item>
</template>
<!-- content begin -->
<router-view />
<router-view v-slot="{ Component }">
<WaterMark content="Pro Layout">
<component :is="Component" />
</WaterMark>
</router-view>
<!-- content end -->
<FooterToolbar>
<template #extra>
......@@ -120,8 +107,8 @@
<script lang="ts">
import { computed, defineComponent, reactive, ref, watchEffect } from 'vue';
import { useRouter } from 'vue-router';
import { Button, Input, Switch, Select, Avatar, Space, Badge, Menu } from 'ant-design-vue';
import { getMenuData, clearMenuItem, FooterToolbar } from '@ant-design-vue/pro-layout';
import { message, Button, Input, Switch, Select, Avatar, Space, Badge, Menu } from 'ant-design-vue';
import { getMenuData, clearMenuItem, WaterMark, FooterToolbar } from '@ant-design-vue/pro-layout';
import type { RouteContextProps } from '@ant-design-vue/pro-layout';
const i18n = (t: string) => t;
......@@ -130,6 +117,8 @@ export default defineComponent({
name: 'BasicLayout',
components: {
FooterToolbar,
WaterMark,
[Button.name]: Button,
[Input.name]: Input,
[Input.Search.name]: Input.Search,
......@@ -137,7 +126,6 @@ export default defineComponent({
[Select.name]: Select,
[Select.Option.displayName!]: Select.Option,
[Space.name]: Space,
[Badge.name]: Badge,
[Avatar.name]: Avatar,
[Menu.Item.name]: Menu.Item,
......@@ -161,7 +149,7 @@ export default defineComponent({
// title: 'ProLayout',
// logo: 'https://alicdn.antdv.com/v2/assets/logo.1ef800a8.svg',
navTheme: 'dark',
layout: 'mix',
layout: 'side',
fixSiderbar: true,
});
const breadcrumb = computed(() =>
......@@ -202,6 +190,9 @@ export default defineComponent({
handlePageLoadingClick,
handleCollapsed,
handleSearch: () => {
message.info('search..');
},
};
},
});
......
This diff is collapsed.
import './index.less';
import './index.less'
import { computed, defineComponent, onBeforeUnmount, onMounted, PropType } from 'vue';
import { RouteContextProps, useRouteContext } from '../RouteContext';
import { getMenuFirstChildren, getPropsSlot, 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 = {
......@@ -25,52 +32,47 @@ const footerToolbarProps = {
type: [Function, Object] as PropType<FooterToolbarProps['getContainer']>,
},
prefixCls: { type: String as PropType<string> },
};
}
const FooterToolbar = defineComponent({
name: 'FooterToolbar',
props: footerToolbarProps,
setup(props, { slots }) {
const routeContext = useRouteContext();
const { getPrefixCls } = routeContext;
const baseClassName = props.prefixCls || getPrefixCls('footer-bar');
// matchMenuKeys
const matchMenuChildrenSize = computed(
() =>
(
(routeContext.menuData &&
getMenuFirstChildren(
routeContext.menuData,
(routeContext.selectedKeys && routeContext.selectedKeys[0]) || undefined,
)) ||
[]
).length,
);
const hasSide = computed(() => {
return routeContext.layout === 'mix' && routeContext.splitMenus
? matchMenuChildrenSize.value > 0
: true;
});
const context = useRouteContext()
const baseClassName = props.prefixCls || context.getPrefixCls('footer-bar')
const hasFlatMenu = computed(() => {
return unref(context.flatMenuData).length > 0
})
const width = computed(() => {
const { isMobile, sideWidth, layout } = routeContext;
if (!sideWidth || layout === 'top') {
return '100%';
const { isMobile, hasSide, siderWidth, layout } = context
if (!siderWidth || layout === 'top') {
return '100%'
}
if (!hasSide.value) {
return '100%';
console.log(
'x',
unref(siderWidth),
'hasFlatMenu',
unref(hasFlatMenu),
'hasSide',
unref(context.hasSide)
)
if (!hasFlatMenu.value && !unref(hasSide)) {
return '100%'
}
return isMobile ? '100%' : `calc(100% - ${sideWidth}px)`;
});
console.log('x2', unref(context.hasSide))
return isMobile ? '100%' : `calc(100% - ${siderWidth}px)`
})
onMounted(() => {
routeContext.setHasFooterToolbar && routeContext.setHasFooterToolbar(true);
});
context.setHasFooterToolbar && context.setHasFooterToolbar(true)
})
onBeforeUnmount(() => {
routeContext.setHasFooterToolbar && routeContext.setHasFooterToolbar(false);
});
context.setHasFooterToolbar && context.setHasFooterToolbar(false)
})
return () => {
const extra = getPropsSlotfn(slots, props, 'extra');
const extra = getPropsSlotfn(slots, props, 'extra')
const dom = () => {
return (
<>
......@@ -79,24 +81,24 @@ const FooterToolbar = defineComponent({
</div>
<div class={`${baseClassName}-right`}>{slots.default?.()}</div>
</>
);
};
)
}
return (
<div class={baseClassName} style={{ width: width.value }}>
{props.renderContent
? props.renderContent(
{
...props,
...routeContext,
...context,
leftWidth: width.value,
},
dom(),
dom()
)
: dom()}
</div>
);
};
)
}
},
});
})
export default FooterToolbar;
export default FooterToolbar
import { InjectionKey, provide, reactive, Ref, VNodeChild, ComputedRef } from 'vue';
import { createContext, useContext } from './hooks/context';
import { MenuDataItem, FormatMessage, WithFalse } from './typings';
import { PureSettings } from './defaultSettings';
import {
InjectionKey,
provide,
reactive,
Ref,
VNodeChild,
ComputedRef,
} from 'vue'
import { createContext, useContext } from './hooks/context'
import { MenuDataItem, FormatMessage, WithFalse } from './typings'
import { PureSettings } from './defaultSettings'
export interface Route {
path: string;
breadcrumbName: string;
children?: Omit<Route, 'children'>[];
path: string
breadcrumbName: string
children?: Omit<Route, 'children'>[]
}
export interface BreadcrumbProps {
prefixCls?: string;
routes?: Route[];
params?: any;
separator?: VNodeChild;
prefixCls?: string
routes?: Route[]
params?: any
separator?: VNodeChild
itemRender?: (opts: {
route: Route;
params: any;
routes: Array<Route>;
paths: Array<string>;
}) => VNodeChild;
route: Route
params: any
routes: Array<Route>
paths: Array<string>
}) => VNodeChild
}
export type BreadcrumbListReturn = Pick<
BreadcrumbProps,
Extract<keyof BreadcrumbProps, 'routes' | 'itemRender'>
>;
>
export interface MenuState {
selectedKeys: string[];
openKeys: string[];
selectedKeys: string[]
openKeys: string[]
}
export interface RouteContextProps extends Partial<PureSettings>, MenuState {
menuData: MenuDataItem[];
menuData: MenuDataItem[]
flatMenuData?: MenuDataItem[]
getPrefixCls?: (suffixCls?: string, customizePrefixCls?: string) => string;
locale?: WithFalse<FormatMessage>;
breadcrumb?: BreadcrumbListReturn | ComputedRef<BreadcrumbListReturn>;
isMobile?: boolean;
prefixCls?: string;
collapsed?: boolean;
hasSideMenu?: boolean;
hasHeader?: boolean;
sideWidth?: number;
headerHeight?: number;
hasFooterToolbar?: boolean;
hasFooter?: boolean;
setHasFooterToolbar?: (bool: boolean) => void;
getPrefixCls?: (suffixCls?: string, customizePrefixCls?: string) => string
locale?: WithFalse<FormatMessage>
breadcrumb?: BreadcrumbListReturn | ComputedRef<BreadcrumbListReturn>
isMobile?: boolean
prefixCls?: string
collapsed?: boolean
hasSideMenu?: boolean
hasHeader?: boolean
siderWidth?: number
headerHeight?: number
hasFooterToolbar?: boolean
hasFooter?: boolean
hasSide?: boolean
setHasFooterToolbar?: (bool: boolean) => void
/* 附加属性 */
[key: string]: any;
[key: string]: any
}
export const defaultPrefixCls = 'ant-pro';
export const defaultPrefixCls = 'ant-pro'
export const getPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `${defaultPrefixCls}-${suffixCls}` : defaultPrefixCls;
};
export const getPrefixCls = (
suffixCls?: string,
customizePrefixCls?: string
) => {
if (customizePrefixCls) return customizePrefixCls
return suffixCls ? `${defaultPrefixCls}-${suffixCls}` : defaultPrefixCls
}
// set default context
export const defaultRouteContext = reactive({
......@@ -65,22 +77,31 @@ export const defaultRouteContext = reactive({
locale: (t: string) => t,
contentWidth: 'Fluid',
hasFooterToolbar: false,
});
})
const routeContextInjectKey: InjectionKey<RouteContextProps> = Symbol('route-context');
const routeContextInjectKey: InjectionKey<RouteContextProps> =
Symbol('route-context')
export const createRouteContext = () =>
createContext<RouteContextProps>(routeContextInjectKey, 'RouteContext.Provider');
createContext<RouteContextProps>(
routeContextInjectKey,
'RouteContext.Provider'
)
export const provideRouteContext = (value: RouteContextProps | Ref<RouteContextProps>) => {
provide(routeContextInjectKey, value);
};
export const provideRouteContext = (
value: RouteContextProps | Ref<RouteContextProps>
) => {
provide(routeContextInjectKey, value)
}
export const useRouteContext = () =>
useContext<Required<RouteContextProps>>(routeContextInjectKey, defaultRouteContext);
useContext<Required<RouteContextProps>>(
routeContextInjectKey,
defaultRouteContext
)
const Provider = createRouteContext();
const Provider = createRouteContext()
export default {
Provider,
};
}
This diff is collapsed.
......@@ -197,6 +197,7 @@
.@{ant-prefix}-menu-submenu-title {
.anticon {
transition: none;
font-size: 16px;
}
}
......
......@@ -68,6 +68,7 @@ const getPixelRatio = (context: any) => {
}
const WaterMark = defineComponent({
name: 'WaterMark',
props: waterMarkProps,
setup(props, { slots }) {
const {
......@@ -145,6 +146,7 @@ const WaterMark = defineComponent({
}
})
return () => {
return (
<div
style={{
......@@ -171,6 +173,7 @@ const WaterMark = defineComponent({
/>
</div>
)
}
},
})
......
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