Commit 9afdc589 authored by Sendya's avatar Sendya

fix: menu selectedKeys

parent 44bb2288
...@@ -42,13 +42,16 @@ export default defineComponent({ ...@@ -42,13 +42,16 @@ export default defineComponent({
state.fixSiderbar = !state.fixSiderbar; state.fixSiderbar = !state.fixSiderbar;
}} }}
/> />
<Switch
checkedChildren="Split Menus"
unCheckedChildren="Un Split Menus"
checked={state.splitMenus}
onChange={() => {
state.splitMenus = !state.splitMenus;
}}
/>
</Space> </Space>
<p> <pre>{JSON.stringify(state, null, 2)}</pre>
<p>block</p>
...
<br />
long text..
</p>
<p> <p>
<p>block</p> <p>block</p>
... ...
......
import 'ant-design-vue/dist/antd.less'; import 'ant-design-vue/dist/antd.less';
import { createApp, defineComponent, watch, ref } from 'vue'; import { createApp, defineComponent, watch, ref } from 'vue';
import { createRouter, createWebHashHistory, useRoute } from 'vue-router'; import { createRouter, createWebHashHistory, useRoute, useRouter, RouteRecord } from 'vue-router';
import { Avatar } from 'ant-design-vue'; import { Avatar } from 'ant-design-vue';
import { UserOutlined } from '@ant-design/icons-vue'; import { UserOutlined } from '@ant-design/icons-vue';
import { default as ProLayout } from '../src/'; import { default as ProLayout } from '../src/';
import { createRouteContext } from '../src/RouteContext'; import { createRouteContext } from '../src/RouteContext';
import { globalState as state } from './state'; import { globalState, globalState as state } from './state';
import registerIcons from './_util/icons'; import registerIcons from './_util/icons';
...@@ -14,13 +14,22 @@ import Page1 from './demo/page1'; ...@@ -14,13 +14,22 @@ import Page1 from './demo/page1';
import Welcome from './demo/welcome'; import Welcome from './demo/welcome';
import FormPage from './demo/form'; import FormPage from './demo/form';
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,
setup() { setup() {
const { getRoutes } = useRouter();
const route = useRoute(); const route = useRoute();
const [RouteContextProvider] = createRouteContext(); const [RouteContextProvider] = createRouteContext();
const menuData = getMenuData(getRoutes());
globalState.menuData = menuData;
const cacheOpenKeys = ref<string[]>([]); const cacheOpenKeys = ref<string[]>([]);
watch( watch(
() => state.collapsed, () => state.collapsed,
...@@ -112,6 +121,7 @@ const routes = [ ...@@ -112,6 +121,7 @@ const routes = [
path: '/dashboard', path: '/dashboard',
name: 'dashboard', name: 'dashboard',
meta: { title: 'dashboard' }, meta: { title: 'dashboard' },
redirect: '/dashboard/analysis',
component: RouteView, component: RouteView,
children: [ children: [
{ {
...@@ -138,6 +148,7 @@ const routes = [ ...@@ -138,6 +148,7 @@ const routes = [
path: '/form', path: '/form',
name: 'form', name: 'form',
meta: { title: 'Form', icon: 'SmileOutlined' }, meta: { title: 'Form', icon: 'SmileOutlined' },
redirect: '/form/basic-form',
component: RouteView, component: RouteView,
children: [ children: [
{ {
...@@ -168,6 +179,7 @@ const router = createRouter({ ...@@ -168,6 +179,7 @@ const router = createRouter({
path: '/', path: '/',
name: 'index', name: 'index',
meta: { title: '' }, meta: { title: '' },
redirect: '/welcome',
component: BasicLayout, component: BasicLayout,
children: routes, children: routes,
}, },
......
import { reactive } from 'vue'; import { reactive } from 'vue';
import { menus } from './menus';
import { RouteContextProps } from '../src/RouteContext'; import { RouteContextProps } from '../src/RouteContext';
export const globalState = reactive<RouteContextProps>({ export const globalState = reactive<RouteContextProps>({
...@@ -12,10 +11,10 @@ export const globalState = reactive<RouteContextProps>({ ...@@ -12,10 +11,10 @@ export const globalState = reactive<RouteContextProps>({
isMobile: false, isMobile: false,
fixSiderbar: false, fixSiderbar: false,
fixedHeader: false, fixedHeader: false,
menuData: menus, menuData: [],
sideWidth: 208, sideWidth: 208,
splitMenus: true, splitMenus: false,
hasSideMenu: true, hasSideMenu: false,
hasHeader: true, hasHeader: true,
hasFooterToolbar: false, hasFooterToolbar: false,
setHasFooterToolbar: (has: boolean) => (globalState.hasFooterToolbar = has), setHasFooterToolbar: (has: boolean) => (globalState.hasFooterToolbar = has),
......
...@@ -72,7 +72,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -72,7 +72,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
emit('update:collapsed', collapsed); emit('update:collapsed', collapsed);
}; };
const handleOpenKeys = (openKeys: string[] | false): void => { const handleOpenKeys = (openKeys: string[] | false): void => {
openKeys && emit('update:open-keys', openKeys); emit('update:open-keys', openKeys);
}; };
const handleSelect = (selectedKeys: string[] | false): void => { const handleSelect = (selectedKeys: string[] | false): void => {
selectedKeys && emit('update:selected-keys', selectedKeys); selectedKeys && emit('update:selected-keys', selectedKeys);
...@@ -239,6 +239,7 @@ ProLayout.props = { ...@@ -239,6 +239,7 @@ ProLayout.props = {
// settings // settings
/* 侧边菜单宽度 */ /* 侧边菜单宽度 */
siderWidth: PropTypes.number.def(208), siderWidth: PropTypes.number.def(208),
splitMenus: PropTypes.bool,
/* 控制菜单的收起和展开 */ /* 控制菜单的收起和展开 */
collapsed: PropTypes.bool, collapsed: PropTypes.bool,
/* 菜单的折叠收起事件 (collapsed: boolean) => void */ /* 菜单的折叠收起事件 (collapsed: boolean) => void */
......
...@@ -6,7 +6,7 @@ import { GlobalHeader, GlobalHeaderProps } from './GlobalHeader'; ...@@ -6,7 +6,7 @@ import { GlobalHeader, GlobalHeaderProps } from './GlobalHeader';
import { TopNavHeader } from './TopNavHeader'; import { TopNavHeader } from './TopNavHeader';
import { useRouteContext } from './RouteContext'; import { useRouteContext } from './RouteContext';
import { RenderVNodeType, WithFalse } from './typings'; import { RenderVNodeType, WithFalse } from './typings';
import { flatMap } from './utils'; import { clearMenuItem, flatMap } from './utils';
import './Header.less'; import './Header.less';
const { Header } = Layout; const { Header } = Layout;
...@@ -56,6 +56,7 @@ export const headerProps = [ ...@@ -56,6 +56,7 @@ export const headerProps = [
'navTheme', 'navTheme',
'onSelect', 'onSelect',
'onOpenChange', 'onOpenChange',
'onOpenKeys',
]; ];
export const HeaderView = defineComponent({ export const HeaderView = defineComponent({
...@@ -76,12 +77,16 @@ export const HeaderView = defineComponent({ ...@@ -76,12 +77,16 @@ export const HeaderView = defineComponent({
onCollapse, onCollapse,
} = toRefs(props); } = toRefs(props);
const context = useRouteContext(); const context = useRouteContext();
const isTop = computed(() => props.layout === 'top' || props.layout === 'mix');
const needFixedHeader = computed(() => fixedHeader.value || layout.value === 'mix'); const needFixedHeader = computed(() => fixedHeader.value || layout.value === 'mix');
const isTop = computed(() => layout.value === 'top');
const needSettingWidth = computed( const needSettingWidth = computed(
() => needFixedHeader.value && hasSiderMenu.value && !isTop.value && !isMobile.value, () => needFixedHeader.value && hasSiderMenu.value && !isTop.value && !isMobile.value,
); );
const clearMenuData = computed(() => (context.menuData && flatMap(context.menuData)) || []); // cache menu
const clearMenuData = computed(
() => (context.menuData && clearMenuItem(context.menuData)) || [],
);
const className = computed(() => { const className = computed(() => {
return { return {
[`${prefixCls.value}-fixed-header`]: needFixedHeader.value, [`${prefixCls.value}-fixed-header`]: needFixedHeader.value,
...@@ -120,32 +125,34 @@ export const HeaderView = defineComponent({ ...@@ -120,32 +125,34 @@ export const HeaderView = defineComponent({
: '100%'; : '100%';
}); });
const right = computed(() => (needFixedHeader.value ? 0 : undefined)); const right = computed(() => (needFixedHeader.value ? 0 : undefined));
return () => ( return () => {
<> return (
{needFixedHeader.value && ( <>
{needFixedHeader.value && (
<Header
style={{
height: `${headerHeight.value}px`,
lineHeight: `${headerHeight.value}px`,
background: 'transparent',
}}
/>
)}
<Header <Header
style={{ style={{
padding: 0,
height: `${headerHeight.value}px`, height: `${headerHeight.value}px`,
lineHeight: `${headerHeight.value}px`, lineHeight: `${headerHeight.value}px`,
background: 'transparent', width: width.value,
zIndex: layout.value === 'mix' ? 100 : 19,
right: right.value,
}} }}
/> class={className.value}
)} >
<Header {renderContent()}
style={{ </Header>
padding: 0, </>
height: `${headerHeight.value}px`, );
lineHeight: `${headerHeight.value}px`, };
width: width.value,
zIndex: layout.value === 'mix' ? 100 : 19,
right: right.value,
}}
class={className.value}
>
{renderContent()}
</Header>
</>
);
}, },
}); });
......
...@@ -8,6 +8,7 @@ import { ...@@ -8,6 +8,7 @@ import {
PropType, PropType,
isVNode, isVNode,
toRefs, toRefs,
toRaw,
} 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';
...@@ -54,6 +55,10 @@ export const VueBaseMenuProps = { ...@@ -54,6 +55,10 @@ export const VueBaseMenuProps = {
type: String as PropType<BaseMenuProps['theme']>, type: String as PropType<BaseMenuProps['theme']>,
default: 'dark', default: 'dark',
}, },
layout: {
type: String as PropType<BaseMenuProps['layout']>,
default: 'side',
},
collapsed: { collapsed: {
type: Boolean as PropType<boolean | undefined>, type: Boolean as PropType<boolean | undefined>,
default: false, default: false,
...@@ -151,6 +156,13 @@ LazyIcon.icon = { ...@@ -151,6 +156,13 @@ LazyIcon.icon = {
type: [String, Function, Object] as PropType<string | Function | VNodeChild | JSX.Element>, type: [String, Function, Object] as PropType<string | Function | VNodeChild | JSX.Element>,
}; };
const getOpenKeysProps = (openKeys: string[] | false, { layout, collapsed }) => {
if (openKeys && !collapsed && ['side', 'mix'].includes(layout || 'mix')) {
return openKeys;
}
return [];
};
export default defineComponent({ export default defineComponent({
name: 'BaseMenu', name: 'BaseMenu',
props: Object.assign( props: Object.assign(
...@@ -167,6 +179,10 @@ export default defineComponent({ ...@@ -167,6 +179,10 @@ export default defineComponent({
setup(props, { emit }) { setup(props, { emit }) {
const { mode, i18n } = toRefs(props); const { mode, i18n } = toRefs(props);
const isInline = computed(() => mode.value === 'inline'); const isInline = computed(() => mode.value === 'inline');
const openKeysProps = computed(() =>
getOpenKeysProps(toRaw(props.openKeys), { layout: props.layout, collapsed: props.collapsed }),
);
const handleOpenChange: OpenEventHandler = (openKeys: string[]): void => { const handleOpenChange: OpenEventHandler = (openKeys: string[]): void => {
emit('update:openKeys', openKeys); emit('update:openKeys', openKeys);
}; };
...@@ -186,7 +202,7 @@ export default defineComponent({ ...@@ -186,7 +202,7 @@ export default defineComponent({
inlineIndent={16} inlineIndent={16}
mode={props.mode} mode={props.mode}
theme={props.theme as 'dark' | 'light'} theme={props.theme as 'dark' | 'light'}
openKeys={props.openKeys || []} openKeys={openKeysProps.value}
selectedKeys={props.selectedKeys || []} selectedKeys={props.selectedKeys || []}
onOpenChange={handleOpenChange} onOpenChange={handleOpenChange}
onSelect={handleSelect} onSelect={handleSelect}
......
...@@ -71,6 +71,7 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = props => { ...@@ -71,6 +71,7 @@ export const TopNavHeader: FunctionalComponent<TopNavHeaderProps> = props => {
light: props.theme === 'light', light: props.theme === 'light',
}; };
}); });
console.log('onOpenKeys', onOpenKeys);
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' : ''}`}>
......
...@@ -43,7 +43,6 @@ export function clearMenuItem(menusData: MenuDataItem[]): MenuDataItem[] { ...@@ -43,7 +43,6 @@ export function clearMenuItem(menusData: MenuDataItem[]): MenuDataItem[] {
} }
delete finalItem.children; delete finalItem.children;
} }
console.log('finalItem', finalItem);
return finalItem; return finalItem;
}) })
.filter(item => item) as MenuDataItem[]; .filter(item => item) as MenuDataItem[];
......
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