mirror of
https://github.com/vbenjs/vue-vben-admin.git
synced 2025-08-27 15:41:32 +08:00
perf: mobile style adjustment
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
import { useLockPage } from '/@/hooks/web/useLockPage';
|
||||
import { useLocale } from '/@/hooks/web/useLocale';
|
||||
import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'App',
|
||||
@@ -25,9 +24,6 @@
|
||||
// Initialize vuex internal system configuration
|
||||
initAppConfigStore();
|
||||
|
||||
// Create a global breakpoint monitor
|
||||
createBreakpointListen();
|
||||
|
||||
// Get ConfigProvider configuration
|
||||
const { transformCellText } = getConfigProvider();
|
||||
|
||||
|
@@ -6,6 +6,12 @@ let globalScreenRef: ComputedRef<sizeEnum | undefined>;
|
||||
let globalWidthRef: ComputedRef<number>;
|
||||
let globalRealWidthRef: ComputedRef<number>;
|
||||
|
||||
export interface CreateCallbackParams {
|
||||
screen: ComputedRef<sizeEnum | undefined>;
|
||||
width: ComputedRef<number>;
|
||||
realWidth: ComputedRef<number>;
|
||||
}
|
||||
|
||||
export function useBreakpoint() {
|
||||
return {
|
||||
screenRef: computed(() => unref(globalScreenRef)),
|
||||
@@ -16,7 +22,7 @@ export function useBreakpoint() {
|
||||
}
|
||||
|
||||
// Just call it once
|
||||
export function createBreakpointListen(fn?: Fn) {
|
||||
export function createBreakpointListen(fn?: (opt: CreateCallbackParams) => void) {
|
||||
const screenRef = ref<sizeEnum>(sizeEnum.XL);
|
||||
const realWidthRef = ref(window.innerWidth);
|
||||
|
||||
@@ -46,8 +52,9 @@ export function createBreakpointListen(fn?: Fn) {
|
||||
useEventListener({
|
||||
el: window,
|
||||
name: 'resize',
|
||||
|
||||
listener: () => {
|
||||
fn && fn();
|
||||
resizeFn();
|
||||
getWindowWidth();
|
||||
},
|
||||
});
|
||||
@@ -56,6 +63,17 @@ export function createBreakpointListen(fn?: Fn) {
|
||||
globalScreenRef = computed(() => unref(screenRef));
|
||||
globalWidthRef = computed((): number => screenMap.get(unref(screenRef)!)!);
|
||||
globalRealWidthRef = computed((): number => unref(realWidthRef));
|
||||
|
||||
function resizeFn() {
|
||||
fn &&
|
||||
fn({
|
||||
screen: globalScreenRef,
|
||||
width: globalWidthRef,
|
||||
realWidth: globalRealWidthRef,
|
||||
});
|
||||
}
|
||||
|
||||
resizeFn();
|
||||
return {
|
||||
screenRef: globalScreenRef,
|
||||
screenEnum,
|
||||
|
@@ -45,6 +45,7 @@ import { MenuModeEnum, MenuSplitTyeEnum } from '/@/enums/menuEnum';
|
||||
import { AppLocalePicker } from '/@/components/Application';
|
||||
import { useI18n } from '/@/hooks/web/useI18n';
|
||||
import { propTypes } from '/@/utils/propTypes';
|
||||
import { useLayoutContext } from '../useLayoutContext';
|
||||
|
||||
interface TooltipItemProps {
|
||||
title: string;
|
||||
@@ -71,6 +72,9 @@ export default defineComponent({
|
||||
|
||||
// const logoWidthRef = ref(200);
|
||||
const logoRef = ref<ComponentRef>(null);
|
||||
|
||||
const injectValue = useLayoutContext();
|
||||
|
||||
const { refreshPage } = useTabs();
|
||||
const { t } = useI18n();
|
||||
|
||||
@@ -116,6 +120,10 @@ export default defineComponent({
|
||||
return theme ? `layout-header__header--${theme}` : '';
|
||||
});
|
||||
|
||||
const isPc = computed(() => {
|
||||
return !unref(injectValue.isMobile);
|
||||
});
|
||||
|
||||
const getSplitType = computed(() => {
|
||||
return unref(getSplit) ? MenuSplitTyeEnum.TOP : MenuSplitTyeEnum.NONE;
|
||||
});
|
||||
@@ -147,11 +155,13 @@ export default defineComponent({
|
||||
{unref(getShowHeaderTrigger) && (
|
||||
<LayoutTrigger theme={unref(getHeaderTheme)} sider={false} />
|
||||
)}
|
||||
{unref(getShowBread) && <LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />}
|
||||
{unref(getShowBread) && unref(isPc) && (
|
||||
<LayoutBreadcrumb showIcon={unref(getShowBreadCrumbIcon)} />
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{unref(getShowTopMenu) && (
|
||||
{unref(getShowTopMenu) && unref(isPc) && (
|
||||
// <div class={[`layout-header__menu `]} style={{ width: `calc(100% - ${width}px)` }}>
|
||||
<div class={[`layout-header__menu `]}>
|
||||
<LayoutMenu
|
||||
@@ -179,7 +189,7 @@ export default defineComponent({
|
||||
function renderAction() {
|
||||
return (
|
||||
<div class={`layout-header__action`}>
|
||||
{unref(getUseErrorHandle) && (
|
||||
{unref(getUseErrorHandle) && unref(isPc) && (
|
||||
<TooltipItem title={t('layout.header.tooltipErrorLog')}>
|
||||
{() => (
|
||||
<Badge
|
||||
@@ -194,25 +204,25 @@ export default defineComponent({
|
||||
</TooltipItem>
|
||||
)}
|
||||
|
||||
{unref(getUseLockPage) && (
|
||||
{unref(getUseLockPage) && unref(isPc) && (
|
||||
<TooltipItem title={t('layout.header.tooltipLock')}>
|
||||
{() => renderActionDefault(LockOutlined, handleLockPage)}
|
||||
</TooltipItem>
|
||||
)}
|
||||
|
||||
{unref(getShowNotice) && (
|
||||
{unref(getShowNotice) && unref(isPc) && (
|
||||
<TooltipItem title={t('layout.header.tooltipNotify')}>
|
||||
{() => <NoticeAction />}
|
||||
</TooltipItem>
|
||||
)}
|
||||
|
||||
{unref(getShowRedo) && (
|
||||
{unref(getShowRedo) && unref(isPc) && (
|
||||
<TooltipItem title={t('layout.header.tooltipRedo')}>
|
||||
{() => renderActionDefault(RedoOutlined, refreshPage)}
|
||||
</TooltipItem>
|
||||
)}
|
||||
|
||||
{unref(getShowFullScreen) && (
|
||||
{unref(getShowFullScreen) && unref(isPc) && (
|
||||
<TooltipItem
|
||||
title={
|
||||
unref(isFullscreenRef)
|
||||
|
@@ -56,7 +56,7 @@ export default defineComponent({
|
||||
(): CSSProperties => {
|
||||
const style: CSSProperties = {};
|
||||
if (unref(getFixed)) {
|
||||
style.width = unref(getCalcContentWidth);
|
||||
style.width = unref(injectValue.isMobile) ? '100%' : unref(getCalcContentWidth);
|
||||
}
|
||||
if (unref(getShowFullHeaderRef)) {
|
||||
style.top = `${unref(fullHeaderHeightRef)}px`;
|
||||
@@ -81,7 +81,7 @@ export default defineComponent({
|
||||
nextTick(() => {
|
||||
const headerEl = unref(headerElRef)?.$el;
|
||||
const tabEl = unref(tabElRef)?.$el;
|
||||
const fullHeaderEl = unref(injectValue.fullHeaderRef)?.$el;
|
||||
const fullHeaderEl = unref(injectValue.fullHeader)?.$el;
|
||||
|
||||
let height = 0;
|
||||
if (headerEl && !unref(getShowFullHeaderRef)) {
|
||||
|
@@ -21,14 +21,20 @@ import { useRootSetting } from '/@/hooks/setting/useRootSetting';
|
||||
import { createLayoutContext } from './useLayoutContext';
|
||||
|
||||
import { registerGlobComp } from '/@/components/registerGlobComp';
|
||||
|
||||
import { createBreakpointListen } from '/@/hooks/event/useBreakpoint';
|
||||
import { isMobile } from '/@/utils/is';
|
||||
export default defineComponent({
|
||||
name: 'DefaultLayout',
|
||||
setup() {
|
||||
const { currentRoute } = useRouter();
|
||||
const headerRef = ref<ComponentRef>(null);
|
||||
const isMobileRef = ref(false);
|
||||
|
||||
createLayoutContext({ fullHeaderRef: headerRef });
|
||||
createLayoutContext({ fullHeader: headerRef, isMobile: isMobileRef });
|
||||
|
||||
createBreakpointListen(() => {
|
||||
isMobileRef.value = isMobile();
|
||||
});
|
||||
|
||||
// ! Only register global components here
|
||||
// ! Can reduce the size of the first screen code
|
||||
|
@@ -81,7 +81,7 @@ export default defineComponent({
|
||||
topRef.value = 0;
|
||||
if (unref(getUnFixedAndFull)) return;
|
||||
nextTick(() => {
|
||||
const fullHeaderEl = unref(injectValue.fullHeaderRef)?.$el;
|
||||
const fullHeaderEl = unref(injectValue.fullHeader)?.$el;
|
||||
if (!fullHeaderEl) return;
|
||||
topRef.value = fullHeaderEl.offsetHeight;
|
||||
});
|
||||
@@ -121,10 +121,9 @@ export default defineComponent({
|
||||
return () => {
|
||||
return (
|
||||
<>
|
||||
{unref(getMenuFixed) && (
|
||||
{unref(getMenuFixed) && !unref(injectValue.isMobile) && (
|
||||
<div style={unref(getHiddenDomStyle)} class={{ hidden: !unref(showClassSideBarRef) }} />
|
||||
)}
|
||||
|
||||
<Layout.Sider
|
||||
ref={sideRef}
|
||||
breakpoint="md"
|
||||
|
@@ -2,7 +2,8 @@ import { InjectionKey, Ref } from 'vue';
|
||||
import { createContext, useContext } from '/@/hooks/core/useContext';
|
||||
|
||||
export interface LayoutContextProps {
|
||||
fullHeaderRef: Ref<ComponentRef>;
|
||||
fullHeader: Ref<ComponentRef>;
|
||||
isMobile: Ref<boolean>;
|
||||
}
|
||||
|
||||
const layoutContextInjectKey: InjectionKey<LayoutContextProps> = Symbol();
|
||||
|
@@ -97,10 +97,10 @@ class Tab extends VuexModule {
|
||||
const pageCacheSet = new Set<string>();
|
||||
this.tabsState.forEach((tab) => {
|
||||
const item = getRoute(tab);
|
||||
const needCache = !item.meta.ignoreKeepAlive;
|
||||
const needCache = !item.meta?.ignoreKeepAlive;
|
||||
if (!needCache) return;
|
||||
|
||||
if (item.meta.affix) {
|
||||
if (item.meta?.affix) {
|
||||
const name = item.name as string;
|
||||
pageCacheSet.add(name);
|
||||
} else if (item.matched && needCache) {
|
||||
|
@@ -73,3 +73,9 @@ export function isImageDom(o: Element) {
|
||||
export const isTextarea = (element: Element | null): element is HTMLTextAreaElement => {
|
||||
return element !== null && element.tagName.toLowerCase() === 'textarea';
|
||||
};
|
||||
|
||||
export const isMobile = (): boolean => {
|
||||
return !!navigator.userAgent.match(
|
||||
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
|
||||
);
|
||||
};
|
||||
|
Reference in New Issue
Block a user