Commit 85db9e26 authored by Sendya's avatar Sendya

feat: add `isMobile` mediaMatchs

parent 7ea945d3
import { computed, FunctionalComponent, CSSProperties, VNodeChild, VNode } from 'vue'; import { computed, FunctionalComponent, CSSProperties, VNodeChild, VNode, unref } 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 { withInstall } from 'ant-design-vue/es/_util/type'; import { withInstall } from 'ant-design-vue/es/_util/type';
...@@ -8,10 +8,13 @@ import { WrapContent } from './WrapContent'; ...@@ -8,10 +8,13 @@ import { WrapContent } from './WrapContent';
import { default as Header, HeaderViewProps } from './Header'; import { default as Header, HeaderViewProps } from './Header';
import { RenderVNodeType, WithFalse } from './typings'; import { RenderVNodeType, WithFalse } from './typings';
import { getComponentOrSlot, PropRenderType, PropTypes } from './utils'; import { getComponentOrSlot, PropRenderType, PropTypes } from './utils';
import useMediaQuery from './hooks/useMediaQuery';
import './BasicLayout.less'; import './BasicLayout.less';
const defaultI18nRender = (key: string) => key; const defaultI18nRender = (key: string) => key;
export type BasicLayoutProps = SiderMenuWrapperProps & export type BasicLayoutProps = SiderMenuWrapperProps &
HeaderViewProps & { HeaderViewProps & {
pure?: boolean; pure?: boolean;
...@@ -60,7 +63,6 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -60,7 +63,6 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
matchMenuKeys, matchMenuKeys,
navTheme, navTheme,
menuData, menuData,
isMobile,
// defaultCollapsed, // defaultCollapsed,
} = props; } = props;
const isTop = computed(() => layout === 'top'); const isTop = computed(() => layout === 'top');
...@@ -68,6 +70,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -68,6 +70,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
// const isMix = computed(() => layout === 'mix'); // const isMix = computed(() => layout === 'mix');
const handleCollapse = (collapsed: boolean) => { const handleCollapse = (collapsed: boolean) => {
console.log('handleCollapse', collapsed);
propsOnCollapse && propsOnCollapse(collapsed); propsOnCollapse && propsOnCollapse(collapsed);
emit('update:collapsed', collapsed); emit('update:collapsed', collapsed);
}; };
...@@ -77,6 +80,8 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -77,6 +80,8 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
const handleSelect = (selectedKeys: string[] | false): void => { const handleSelect = (selectedKeys: string[] | false): void => {
selectedKeys && emit('update:selected-keys', selectedKeys); selectedKeys && emit('update:selected-keys', selectedKeys);
}; };
const colSize = useMediaQuery();
const isMobile = computed(() => (colSize.value === 'sm' || colSize.value === 'xs') && !props.disableMobile);
const baseClassName = computed(() => `${props.prefixCls}-basicLayout`); const baseClassName = computed(() => `${props.prefixCls}-basicLayout`);
// gen className // gen className
const className = computed(() => { const className = computed(() => {
...@@ -87,6 +92,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -87,6 +92,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
[`${baseClassName.value}-is-children`]: props.isChildrenLayout, [`${baseClassName.value}-is-children`]: props.isChildrenLayout,
[`${baseClassName.value}-fix-siderbar`]: props.fixSiderbar, [`${baseClassName.value}-fix-siderbar`]: props.fixSiderbar,
[`${baseClassName.value}-${props.layout}`]: props.layout, [`${baseClassName.value}-${props.layout}`]: props.layout,
[colSize.value]: colSize.value,
}; };
}); });
...@@ -116,7 +122,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -116,7 +122,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
...props, ...props,
hasSiderMenu: !isTop.value, hasSiderMenu: !isTop.value,
menuData, menuData,
isMobile, isMobile: unref(isMobile),
onCollapse: handleCollapse, onCollapse: handleCollapse,
onSelect: handleSelect, onSelect: handleSelect,
onOpenKeys: handleOpenKeys, onOpenKeys: handleOpenKeys,
...@@ -143,6 +149,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots } ...@@ -143,6 +149,7 @@ const ProLayout: FunctionalComponent<BasicLayoutProps> = (props, { emit, slots }
{!isTop.value && ( {!isTop.value && (
<SiderMenuWrapper <SiderMenuWrapper
{...props} {...props}
isMobile={isMobile.value}
menuHeaderRender={ menuHeaderRender={
menuHeaderRenderFunc || (menuHeaderRenderSlot && (() => menuHeaderRenderSlot())) menuHeaderRenderFunc || (menuHeaderRenderSlot && (() => menuHeaderRenderSlot()))
} }
......
...@@ -109,6 +109,8 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -109,6 +109,8 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
props.collapsed ? props.collapsedWidth : props.siderWidth, props.collapsed ? props.collapsedWidth : props.siderWidth,
); );
console.log('runtimeSideWidth', runtimeSideWidth);
const classNames = computed(() => { const classNames = computed(() => {
return { return {
[baseClassName]: true, [baseClassName]: true,
......
...@@ -9,8 +9,23 @@ export type SiderMenuWrapperProps = SiderMenuProps & Partial<PrivateSiderMenuPro ...@@ -9,8 +9,23 @@ export type SiderMenuWrapperProps = SiderMenuProps & Partial<PrivateSiderMenuPro
const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = props => { const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = props => {
return props.isMobile ? ( return props.isMobile ? (
<Drawer> <Drawer
<SiderMenu {...props} /> visible={!props.collapsed}
closable={false}
placement={'left'}
style={{
padding: 0,
height: '100vh',
}}
onClose={() => props.onCollapse(true)}
width={props.siderWidth}
bodyStyle={{ height: '100vh', padding: 0, display: 'flex', flexDirection: 'row' }}
>
<SiderMenu
{...props}
collapsed={props.isMobile ? false : props.collapsed}
splitMenus={false}
/>
</Drawer> </Drawer>
) : ( ) : (
<SiderMenu {...props} /> <SiderMenu {...props} />
......
import { ref } from 'vue';
export const MediaQueryEnum = {
xs: {
maxWidth: 575,
matchMedia: '(max-width: 575px)',
},
sm: {
minWidth: 576,
maxWidth: 767,
matchMedia: '(min-width: 576px) and (max-width: 767px)',
},
md: {
minWidth: 768,
maxWidth: 991,
matchMedia: '(min-width: 768px) and (max-width: 991px)',
},
lg: {
minWidth: 992,
maxWidth: 1199,
matchMedia: '(min-width: 992px) and (max-width: 1199px)',
},
xl: {
minWidth: 1200,
maxWidth: 1599,
matchMedia: '(min-width: 1200px) and (max-width: 1599px)',
},
xxl: {
minWidth: 1600,
matchMedia: '(min-width: 1600px)',
},
};
export type MediaQueryKey = keyof typeof MediaQueryEnum;
/**
* loop query screen className
* Array.find will throw a error
* `Rendered more hooks than during the previous render.`
* So should use Array.forEach
*/
export const getScreenClassName = () => {
let className: MediaQueryKey = 'md';
// support ssr
if (typeof window === 'undefined') {
return className;
}
const mediaQueryKey = (Object.keys(MediaQueryEnum) as MediaQueryKey[]).find(key => {
const { matchMedia } = MediaQueryEnum[key];
if (window.matchMedia(matchMedia).matches) {
return true;
}
return false;
});
className = (mediaQueryKey as unknown) as MediaQueryKey;
return className;
};
const useMedia = () => {
const colSpan = ref<string>(getScreenClassName());
Object.keys(MediaQueryEnum).forEach(key => {
const { matchMedia } = MediaQueryEnum[key];
const query = window.matchMedia(matchMedia);
if (query.matches) {
colSpan.value = key;
}
query.onchange = e => {
if (e.matches) {
colSpan.value = key;
}
};
});
return colSpan;
};
export default useMedia;
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