Unverified Commit ba92fdff authored by Sendya's avatar Sendya

fix: breadcrumbRender

parent 34b61562
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import { PageContainer } from '../../src';
export default defineComponent({ export default defineComponent({
setup() { setup() {
const route = useRoute(); const route = useRoute();
return () => ( return () => (
<div> <PageContainer>
<h1>Form: {route.meta.title}</h1> <h1>Form: {route.meta.title}</h1>
<pre>{JSON.stringify(route.meta, null, 4)}</pre> <pre>{JSON.stringify(route.meta, null, 4)}</pre>
</div> </PageContainer>
); );
}, },
}); });
import 'ant-design-vue/dist/antd.less'; import 'ant-design-vue/dist/antd.less';
import { createApp, defineComponent, watch, ref, watchEffect, onMounted } from 'vue'; import { createApp, defineComponent, watch, ref, watchEffect, onMounted } from 'vue';
import { createRouter, createWebHashHistory, useRoute, useRouter, RouteRecord } from 'vue-router'; import { createRouter, createWebHashHistory, useRoute, useRouter, RouterLink } from 'vue-router';
import { Avatar, Button, Space, Select, Switch } from 'ant-design-vue'; import { Avatar, Button, Space, Select, Switch } from 'ant-design-vue';
import { UserOutlined } from '@ant-design/icons-vue'; import { UserOutlined } from '@ant-design/icons-vue';
import { default as ProLayout, FooterToolbar, WaterMark, FormatMessage } from '../src/'; import { default as ProLayout, FooterToolbar, WaterMark, getMenuData } from '../src/';
import { globalState as state } from './state'; import { globalState as state } from './state';
import './demo.less'; import './demo.less';
...@@ -27,11 +27,6 @@ const i18n = (key: string): string => { ...@@ -27,11 +27,6 @@ const i18n = (key: string): string => {
return locales[key] || key; return locales[key] || key;
}; };
const getMenuData = (routes: RouteRecord[]) => {
const childrenRoute = routes.find(route => route.path === '/');
return childrenRoute?.children || [];
};
const BasicLayout = defineComponent({ const BasicLayout = defineComponent({
name: 'BasicLayout', name: 'BasicLayout',
inheritAttrs: false, inheritAttrs: false,
...@@ -39,7 +34,7 @@ const BasicLayout = defineComponent({ ...@@ -39,7 +34,7 @@ const BasicLayout = defineComponent({
const { getRoutes } = useRouter(); const { getRoutes } = useRouter();
const route = useRoute(); const route = useRoute();
const menuData = getMenuData(getRoutes()); const { menuData, breadcrumb } = getMenuData(getRoutes());
const updateSelectedMenu = () => { const updateSelectedMenu = () => {
const matched = route.matched.concat().map(item => item.path); const matched = route.matched.concat().map(item => item.path);
...@@ -82,6 +77,7 @@ const BasicLayout = defineComponent({ ...@@ -82,6 +77,7 @@ const BasicLayout = defineComponent({
siderWidth={state.sideWidth} siderWidth={state.sideWidth}
splitMenus={state.splitMenus} splitMenus={state.splitMenus}
menuData={menuData} menuData={menuData}
breadcrumbData={breadcrumb}
collapsed={state.collapsed} collapsed={state.collapsed}
openKeys={state.openKeys} openKeys={state.openKeys}
selectedKeys={state.selectedKeys} selectedKeys={state.selectedKeys}
...@@ -108,6 +104,13 @@ const BasicLayout = defineComponent({ ...@@ -108,6 +104,13 @@ const BasicLayout = defineComponent({
{state.collapsed && state.layout !== 'mix' ? null : <h1>Pro Preview</h1>} {state.collapsed && state.layout !== 'mix' ? null : <h1>Pro Preview</h1>}
</a> </a>
)} )}
breadcrumbRender={({ route: r, routes, paths }) =>
routes.indexOf(r) === routes.length - 1 ? (
<span>{r.breadcrumbName}</span>
) : (
<RouterLink to={{ path: `/${paths.join('/')}` }}>{r.breadcrumbName}</RouterLink>
)
}
// {...{ // {...{
// 'onUpdate:collapsed': noop, // 'onUpdate:collapsed': noop,
// 'onUpdate:openKeys': noop, // 'onUpdate:openKeys': noop,
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
}, },
"peerDependencies": { "peerDependencies": {
"ant-design-vue": "^2.0.0", "ant-design-vue": "^2.0.0",
"vue-router": "^4.0.3",
"vue": ">=3.0.0" "vue": ">=3.0.0"
}, },
"devDependencies": { "devDependencies": {
......
...@@ -2,7 +2,7 @@ import { computed, CSSProperties, reactive, unref, provide, defineComponent, toR ...@@ -2,7 +2,7 @@ import { computed, CSSProperties, reactive, unref, provide, defineComponent, toR
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 { withInstall } from 'ant-design-vue/es/_util/type'; import { withInstall } from 'ant-design-vue/es/_util/type';
import { getPrefixCls, RouteContextProps } from './RouteContext'; import { BreadcrumbProps, getPrefixCls, RouteContextProps } from './RouteContext';
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';
...@@ -32,6 +32,10 @@ export type BasicLayoutProps = SiderMenuWrapperProps & ...@@ -32,6 +32,10 @@ export type BasicLayoutProps = SiderMenuWrapperProps &
headerRender?: WithFalse<(props: any /* HeaderProps */) => CustomRender>; headerRender?: WithFalse<(props: any /* HeaderProps */) => CustomRender>;
breadcrumbRender?: WithFalse<BreadcrumbProps['itemRender']>;
breadcrumbData?: BreadcrumbProps['routes'];
colSize?: string; colSize?: string;
/** /**
* 是否禁用移动端模式,有的管理系统不需要移动端模式,此属性设置为true即可 * 是否禁用移动端模式,有的管理系统不需要移动端模式,此属性设置为true即可
...@@ -116,6 +120,9 @@ const ProLayout = defineComponent({ ...@@ -116,6 +120,9 @@ const ProLayout = defineComponent({
const footerRender = getCustomRender(props, slots, 'footerRender'); const footerRender = getCustomRender(props, slots, 'footerRender');
// const menuRender = getCustomRender(props, slots, 'menuRender'); // const menuRender = getCustomRender(props, slots, 'menuRender');
const breadcrumbRender = getCustomRender(props, slots, 'breadcrumbRender');
console.log('breadcrumbRender', breadcrumbRender);
const headerDom = computed(() => const headerDom = computed(() =>
headerRender( headerRender(
{ {
...@@ -141,6 +148,10 @@ const ProLayout = defineComponent({ ...@@ -141,6 +148,10 @@ const ProLayout = defineComponent({
const routeContext: RouteContextProps = reactive({ const routeContext: RouteContextProps = reactive({
getPrefixCls, getPrefixCls,
i18n: props.locale || ((t: string) => t), i18n: props.locale || ((t: string) => t),
breadcrumb: {
routes: propRefs.breadcrumbData,
itemRender: breadcrumbRender,
},
contentWidth: 'Fluid', contentWidth: 'Fluid',
layout: propRefs.layout, layout: propRefs.layout,
navTheme: propRefs.navTheme, navTheme: propRefs.navTheme,
......
...@@ -148,11 +148,13 @@ const defaultPageHeaderRender = ( ...@@ -148,11 +148,13 @@ const defaultPageHeaderRender = (
if (!title && title !== false) { if (!title && title !== false) {
pageHeaderTitle = value.title; pageHeaderTitle = value.title;
} }
console.log('value.breadcrumb', value.breadcrumb);
// inject value // inject value
return ( return (
<PageHeader <PageHeader
title={pageHeaderTitle} title={pageHeaderTitle}
{...restProps} {...restProps}
breadcrumb={{ routes: value.breadcrumb?.routes, itemRender: value.breadcrumb?.itemRender }}
footer={renderFooter({ footer={renderFooter({
...restProps, ...restProps,
tabList, tabList,
...@@ -219,4 +221,6 @@ const PageContainer: FunctionalComponent<PageContainerProps> = (props, { slots } ...@@ -219,4 +221,6 @@ const PageContainer: FunctionalComponent<PageContainerProps> = (props, { slots }
); );
}; };
PageContainer.displayName = 'page-container';
export default withInstall(PageContainer); export default withInstall(PageContainer);
import { InjectionKey, reactive, VNodeChild } from 'vue'; import { InjectionKey, reactive, VNodeChild } from 'vue';
import { createContext, useContext } from './hooks/context'; import { createContext, useContext } from './hooks/context';
import { MenuDataItem } from './typings'; import { MenuDataItem, CustomRender } from './typings';
import { PureSettings } from './defaultSettings'; import { PureSettings } from './defaultSettings';
export interface Route { export interface Route {
path: string; path: string;
...@@ -18,7 +18,7 @@ export interface BreadcrumbProps { ...@@ -18,7 +18,7 @@ export interface BreadcrumbProps {
params: any; params: any;
routes: Array<Route>; routes: Array<Route>;
paths: Array<string>; paths: Array<string>;
}) => VNodeChild; }) => CustomRender;
} }
export type BreadcrumbListReturn = Pick< export type BreadcrumbListReturn = Pick<
......
...@@ -142,11 +142,11 @@ const WaterMark: FC<WaterMarkProps> = (props, { slots }) => { ...@@ -142,11 +142,11 @@ const WaterMark: FC<WaterMarkProps> = (props, { slots }) => {
style={{ style={{
position: 'relative', position: 'relative',
}} }}
class={wrapperCls} class={wrapperCls.value}
> >
{slots.default?.()} {slots.default?.()}
<div <div
class={waterMakrCls} class={waterMakrCls.value}
style={{ style={{
zIndex, zIndex,
position: 'absolute', position: 'absolute',
......
...@@ -16,6 +16,9 @@ export interface WrapContentProps { ...@@ -16,6 +16,9 @@ export interface WrapContentProps {
} }
export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slots, attrs }) => { export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slots, attrs }) => {
if (props.isChildrenLayout) {
return slots.default?.();
}
const { getPrefixCls } = toRefs(useRouteContext()); const { getPrefixCls } = toRefs(useRouteContext());
const prefixCls = getPrefixCls.value('basicLayout'); const prefixCls = getPrefixCls.value('basicLayout');
const classNames = computed(() => { const classNames = computed(() => {
...@@ -33,3 +36,4 @@ export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slot ...@@ -33,3 +36,4 @@ export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slot
}; };
WrapContent.inheritAttrs = false; WrapContent.inheritAttrs = false;
WrapContent.displayName = 'wrap-content';
export * from './RouteContext'; export * from './RouteContext';
export * from './typings'; export * from './typings';
export * from './utils/getMenuData';
export { createContext, useContext, ContextType, CreateContext } from './hooks/context'; export { createContext, useContext, ContextType, CreateContext } from './hooks/context';
export { default as FooterToolbar } from './FooterToolbar'; export { default as FooterToolbar } from './FooterToolbar';
export { default as GlobalFooter } from './GlobalFooter'; export { default as GlobalFooter } from './GlobalFooter';
...@@ -12,7 +13,7 @@ export { WrapContent } from './WrapContent'; ...@@ -12,7 +13,7 @@ export { WrapContent } from './WrapContent';
// ProProviderData, // ProProviderData,
// } from './ProProvider'; // } from './ProProvider';
export { default as PageContainer } from './PageContainer'; export { default as PageContainer } from './PageContainer';
export { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu/index'; export { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu';
export { export {
default as BaseMenu, default as BaseMenu,
BaseMenuProps, BaseMenuProps,
......
import { RouteRecordRaw } from 'vue-router';
export type MenuData = {
menuData: RouteRecordRaw[];
breadcrumb: Record<string, any>;
};
const formatRelativePath = (
routes: RouteRecordRaw[],
breadcrumb: Record<string, any>,
parent?: RouteRecordRaw,
): RouteRecordRaw[] => {
// 计算路由绝对路径
return routes.map(route => {
if (route.path.startsWith('/')) {
return route;
}
if (parent) {
route.path = `${parent.path || ''}/${route.path}`;
} else {
route.path = `/${route.path}`;
}
route.path = route.path.replace('//', '/');
// format children routes
if (route.children && route.children.length > 0) {
route.children = formatRelativePath(route.children, route);
}
breadcrumb[`${route.path}`] = route;
return route;
});
};
export const getMenuData = (routes: RouteRecordRaw[]): MenuData => {
const childrenRoute = routes.find(route => route.path === '/');
const breadcrumb: Record<string, any> = {};
return {
menuData: formatRelativePath(childrenRoute?.children || ([] as RouteRecordRaw[]), breadcrumb),
breadcrumb,
};
};
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