Commit dfab7a66 authored by Sendya's avatar Sendya

feat: test menu

parent e0039d25
......@@ -2,7 +2,9 @@ import { createApp, onMounted, reactive, watch, watchEffect } from 'vue';
import { menus } from './menus';
import { MenuTheme } from '../src/typings';
import { Card, Space, Button, Switch } from 'ant-design-vue';
import BaseMenu, { useMenuState, MenuMode } from '../src/SiderMenu/BaseMenu';
import { useMenu } from '../src/hooks/useMenu';
import { RouterLink } from './mock-router';
import { default as BaseMenu, MenuMode } from '../src/SiderMenu/BaseMenu';
import * as Icon from '@ant-design/icons-vue';
import 'ant-design-vue/dist/antd.less';
......@@ -15,10 +17,10 @@ const BaseMenuDemo = {
themeChecked: true,
modeChecked: true,
})
const [menuState] = useMenuState({
const [menuState] = useMenu({
collapsed: false,
openKeys: ['/dashboard'] as string[],
selectedKeys: ['/dashboard/monitor'] as string[],
openKeys: ['/dashboard'],
selectedKeys: ['/dashboard/monitor'],
})
onMounted(() => {
......@@ -89,4 +91,4 @@ Object.keys(Icon)
app.component(Icon[k].displayName, Icon[k])
})
app.mount('#__vue-content>div');
app.use(RouterLink).mount('#__vue-content>div');
......@@ -4,7 +4,6 @@ import { RouterLink } from './mock-router';
import { Button, Avatar, message } from 'ant-design-vue';
import { default as ProLayout } from '../src/';
import { menus } from './menus';
import { useMenuState } from '../src/SiderMenu/BaseMenu';
import * as Icon from '@ant-design/icons-vue';
import { createRouteContext } from '../src/RouteContext';
......
......@@ -5,31 +5,23 @@ import './side-menu.less';
import { Layout, Input, Space, Switch, message } from 'ant-design-vue';
import { menus } from './menus';
import { default as SiderMenuWrapper } from '../src/SiderMenu';
import { useMenuState } from '../src/SiderMenu/BaseMenu';
import { useMenu } from '../src/hooks/useMenu';
import * as Icon from '@ant-design/icons-vue';
import { MenuTheme } from '../src/typings';
const DemoComponent = {
setup() {
const [menuState] = useMenuState({
const [menuState] = useMenu({
collapsed: false,
openKeys: [''],
selectedKeys: ['/welcome'],
});
const state = reactive({
theme: 'dark',
})
theme: 'light',
});
const handleCollapse = (collapsed: boolean) => {
menuState.collapsed = collapsed;
};
const handleOpenChange = (openKeys: string[]) => {
menuState.openKeys = openKeys;
};
const handleSelect = (selectedKeys: string[]) => {
menuState.selectedKeys = selectedKeys;
};
}
return () => (
<div class="components">
<h2># SideMenu</h2>
......@@ -48,10 +40,8 @@ const DemoComponent = {
isMobile={false}
collapsed={menuState.collapsed}
menuData={menus}
openKeys={menuState.openKeys}
selectedKeys={menuState.selectedKeys}
onOpenChange={handleOpenChange}
onSelect={handleSelect}
// openKeys={menuState.openKeys}
// selectedKeys={menuState.selectedKeys}
onCollapse={handleCollapse}
matchMenuKeys={[]}
contentWidth={'Fixed'}
......
import {
defineComponent,
resolveComponent,
ref,
reactive,
computed,
Ref,
watch,
ComputedRef,
VNodeChild,
VNode,
WatchStopHandle,
PropType,
isVNode,
toRefs,
} from 'vue';
import { createFromIconfontCN } from '@ant-design/icons-vue';
import 'ant-design-vue/es/menu/style';
import Menu from 'ant-design-vue/es/menu';
import Menu, { MenuProps } from 'ant-design-vue/es/menu';
import defaultSettings, { PureSettings } from '../defaultSettings';
import { isImg, isUrl } from '../utils';
import { MenuMode, SelectInfo, OpenEventHandler } from './typings';
import { MenuDataItem, MenuTheme, FormatMessage, WithFalse } from '../typings';
import { PrivateSiderMenuProps } from './SiderMenu';
import './index.less';
import { useMenuState } from '../hooks/useMenu';
export { MenuMode, SelectInfo, OpenEventHandler };
export interface MenuState {
collapsed?: boolean | false;
selectedKeys?: string[];
openKeys?: string[];
}
interface MenuStated {
collapsed: boolean;
selectedKeys: string[];
openKeys: string[];
}
export type MenuStateWatched = [MenuStated, WatchStopHandle];
export function useMenuState({
collapsed = false,
openKeys = [] as string[],
selectedKeys = [] as string[],
}: MenuState): MenuStateWatched {
const state = reactive<MenuStated>({
collapsed,
selectedKeys,
openKeys,
});
const cachedOpenKeys: Ref<string[]> = ref([] as string[]);
const watchRef = watch(
() => state.collapsed,
collapsed => {
if (collapsed) {
cachedOpenKeys.value = state.openKeys.concat();
state.openKeys = [];
} else {
state.openKeys = cachedOpenKeys.value.concat();
}
},
);
return [state, watchRef];
}
export function useRootSubmenuKeys(menus: MenuDataItem[]): ComputedRef<string[]> {
return computed(() => menus.map(it => it.path));
}
// ts typo
export interface BaseMenuProps extends Partial<PureSettings> {
export interface BaseMenuProps extends Partial<PureSettings>, PrivateSiderMenuProps {
prefixCls?: string;
collapsed?: boolean;
splitMenus?: boolean;
......@@ -101,16 +56,16 @@ export const VueBaseMenuProps = {
default: 'dark',
},
collapsed: {
type: Boolean as PropType<boolean>,
type: Boolean as PropType<boolean | undefined>,
default: false,
},
openKeys: {
type: Array as PropType<WithFalse<string[]>>,
required: true,
default: undefined,
},
selectedKeys: {
type: Array as PropType<WithFalse<string[]>>,
required: true,
default: undefined,
},
};
......@@ -212,8 +167,10 @@ export default defineComponent({
emits: ['update:openKeys', 'update:selectedKeys'],
setup(props, { emit }) {
const { mode, i18n } = toRefs(props);
const state = useMenuState();
const isInline = computed(() => mode.value === 'inline');
const handleOpenChange: OpenEventHandler = (openKeys): void => {
const handleOpenChange: OpenEventHandler = (openKeys: string[]): void => {
state?.setOpenKeys(openKeys);
emit('update:openKeys', openKeys);
};
const handleSelect = (params: {
......@@ -223,6 +180,7 @@ export default defineComponent({
domEvent: MouseEvent;
selectedKeys: string[];
}): void => {
state?.setSelectedKeys(params.selectedKeys);
emit('update:selectedKeys', params.selectedKeys);
};
return () => (
......@@ -232,8 +190,8 @@ export default defineComponent({
inlineIndent={16}
mode={props.mode}
theme={props.theme as 'dark' | 'light'}
openKeys={props.openKeys || []}
selectedKeys={props.selectedKeys || []}
openKeys={props.openKeys || state?.openKeys.value || []}
selectedKeys={props.selectedKeys || state?.selectedKeys.value || []}
onOpenChange={handleOpenChange}
onSelect={handleSelect}
>
......
......@@ -121,7 +121,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
const extraDom = menuExtraRender && menuExtraRender(props);
const defaultMenuDom = (
<BaseMenu
theme={props.navTheme === 'realDark' ? 'dark' : props.navTheme}
theme={navTheme === 'realDark' ? 'dark' : navTheme}
mode="inline"
menuData={context.menuData}
collapsed={props.collapsed}
......@@ -157,6 +157,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
)}
<Sider
class={classNames.value}
theme={navTheme === 'realDark' ? 'dark' : navTheme}
width={siderWidth}
breakpoint={breakpoint || undefined}
collapsed={collapsed}
......
import {
ref,
reactive,
watch,
provide,
inject,
InjectionKey,
Ref,
WatchStopHandle,
toRefs,
ToRefs,
} from 'vue';
export interface MenuState {
collapsed?: boolean | false;
selectedKeys?: string[];
openKeys?: string[];
}
export type MenuHandles = {
setCollapsed: (collapsed: boolean) => void;
setSelectedKeys: (selectedKeys: string[]) => void;
setOpenKeys: (openKeys: string[]) => void;
};
export type MenuStated = Required<MenuState>;
export type MenuStateWatched = [MenuStated, MenuHandles, WatchStopHandle];
export const MenuStateKey: InjectionKey<ToRefs<MenuStated> & MenuHandles> = Symbol('menu-state');
export function useMenu({ collapsed = false, openKeys = [], selectedKeys = [] }: MenuState) {
const cacheKeys: Ref<string[]> = ref([] as string[]);
const state = reactive<MenuStated>({
collapsed,
selectedKeys,
openKeys,
});
const setCollapsed = (collapsed = false) => {
state.collapsed = collapsed;
};
const setSelectedKeys = (selectedKeys: string[]) => {
state.selectedKeys = selectedKeys;
};
const setOpenKeys = (openKeys: string[]) => {
state.openKeys = openKeys;
};
provide(MenuStateKey, {
...toRefs(state),
setCollapsed,
setSelectedKeys,
setOpenKeys,
});
const watchRef = watch(
() => state.collapsed,
collapsed => {
if (collapsed) {
cacheKeys.value = state.openKeys.concat();
state.openKeys = [];
} else {
state.openKeys = cacheKeys.value.concat();
}
},
);
return [state, { setCollapsed, setSelectedKeys, setOpenKeys }, watchRef] as MenuStateWatched;
}
export function useMenuState(): Readonly<ToRefs<MenuStated>> & MenuHandles {
return inject(MenuStateKey);
}
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