mirror of
https://gitee.com/xiaonuobase/snowy.git
synced 2026-10-06 06:52:58 +08:00
【底座】平板适配更舒服
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
v-if="isModal"
|
||||
v-bind="attrs"
|
||||
:open="isOpen"
|
||||
:width="modalWidth"
|
||||
:width="calcModalWidth"
|
||||
:footer="slots.footer ? undefined : null"
|
||||
:wrap-class-name="`xn-form-modal ${wrapClassName} ${fullscreenClass}`"
|
||||
:bodyStyle="calcBodyStyle"
|
||||
@@ -238,6 +238,22 @@
|
||||
// Tooltip 挂载 body, 防止拖拽后定位错位
|
||||
const getTooltipContainer = () => document.body
|
||||
|
||||
/************************* 尺寸钳制 *************************/
|
||||
// 视口宽高,用于把业务设定的固定尺寸钳制在屏幕范围内
|
||||
const viewportWidth = ref(window.innerWidth)
|
||||
const viewportHeight = ref(window.innerHeight)
|
||||
|
||||
// 把尺寸解析为像素数值,非固定像素(百分比、vw、calc 等)返回 null 不参与钳制
|
||||
const parsePxSize = (size) => {
|
||||
if (typeof size === 'number') {
|
||||
return Number.isFinite(size) ? size : null
|
||||
}
|
||||
if (typeof size === 'string') {
|
||||
const matched = /^\s*(\d+(\.\d+)?)\s*(px)?\s*$/.exec(size)
|
||||
return matched ? Number(matched[1]) : null
|
||||
}
|
||||
return null
|
||||
}
|
||||
/************************* 对话框 *************************/
|
||||
// 响应式对话框
|
||||
const modalContentRef = ref()
|
||||
@@ -245,6 +261,15 @@
|
||||
// 响应式对话框宽度
|
||||
const modalWidth = ref(props.width)
|
||||
|
||||
// 对话框最终宽度:业务设定的宽度超过视口时收敛为视口宽度,避免弹窗溢出布局
|
||||
const calcModalWidth = computed(() => {
|
||||
const pxWidth = parsePxSize(modalWidth.value)
|
||||
if (pxWidth !== null && pxWidth > viewportWidth.value) {
|
||||
return viewportWidth.value
|
||||
}
|
||||
return modalWidth.value
|
||||
})
|
||||
|
||||
// 响应式对话框高度
|
||||
const modalHeight = ref('auto')
|
||||
|
||||
@@ -427,12 +452,22 @@
|
||||
// 抽屉宽度
|
||||
const drawerWidth = computed(() => {
|
||||
if (isSmallScreen.value || drawerFullscreen.value) return '100%'
|
||||
// 业务设定的宽度超过视口时占满整屏,避免抽屉溢出布局
|
||||
const pxWidth = parsePxSize(baseDrawerWidth.value)
|
||||
if (pxWidth !== null && pxWidth > viewportWidth.value) {
|
||||
return '100%'
|
||||
}
|
||||
return baseDrawerWidth.value
|
||||
})
|
||||
|
||||
// 抽屉高度
|
||||
const drawerHeight = computed(() => {
|
||||
if (isSmallScreen.value || drawerFullscreen.value) return '100%'
|
||||
// 业务设定的高度超过视口时占满整屏(上下方向抽屉)
|
||||
const pxHeight = parsePxSize(baseDrawerHeight.value)
|
||||
if (pxHeight !== null && pxHeight > viewportHeight.value) {
|
||||
return '100%'
|
||||
}
|
||||
return baseDrawerHeight.value
|
||||
})
|
||||
|
||||
@@ -544,6 +579,8 @@
|
||||
// 监听窗口大小变化
|
||||
const handleResize = () => {
|
||||
isSmallScreen.value = window.innerWidth <= 768
|
||||
viewportWidth.value = window.innerWidth
|
||||
viewportHeight.value = window.innerHeight
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
@@ -25,8 +25,12 @@
|
||||
const isMobile = computed(() => {
|
||||
return store.isMobile
|
||||
})
|
||||
const layoutTags = computed(() => {
|
||||
return store.layoutTags
|
||||
const layoutTagsOpen = computed(() => {
|
||||
return store.layoutTagsOpen
|
||||
})
|
||||
// 窄屏或未开启多标签时多标签栏不显示,此时内嵌页只保留当前一个,其余情况随多标签共存
|
||||
const iframeSingleMode = computed(() => {
|
||||
return isMobile.value || !layoutTagsOpen.value
|
||||
})
|
||||
|
||||
watch(route, () => {
|
||||
@@ -41,12 +45,12 @@
|
||||
const clearIframeList = iStore.clearIframeList
|
||||
const push = (route) => {
|
||||
if (route.meta.type === 'iframe') {
|
||||
if (isMobile || !layoutTags) {
|
||||
if (iframeSingleMode.value) {
|
||||
setIframeList(route)
|
||||
} else {
|
||||
pushIframeList(route)
|
||||
}
|
||||
} else if (isMobile || !layoutTags) {
|
||||
} else if (iframeSingleMode.value) {
|
||||
clearIframeList()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div class="layout-items-center" v-if="moduleUnfoldOpen && layout !== layoutEnum.TOP">
|
||||
<!-- 平板尺寸下不展开模块坞,统一走下方紧凑的模块切换风格,避免顶栏被撑爆 -->
|
||||
<div class="layout-items-center" v-if="moduleUnfoldOpen && layout !== layoutEnum.TOP && !isTablet">
|
||||
<a-menu
|
||||
v-model:selectedKeys="selectedKeys"
|
||||
mode="horizontal"
|
||||
@@ -22,7 +23,7 @@
|
||||
</a-menu>
|
||||
</div>
|
||||
<div v-else>
|
||||
<a-popover v-if="menu.length > 1 && !isMobile" placement="bottomLeft">
|
||||
<a-popover v-if="menu.length > 1 && !isPhone" placement="bottomLeft">
|
||||
<template #content>
|
||||
<a-row :gutter="[0, 5]" class="module-row">
|
||||
<div v-for="item in menu" :key="item.id">
|
||||
@@ -64,6 +65,14 @@
|
||||
const isMobile = computed(() => {
|
||||
return store.isMobile
|
||||
})
|
||||
// 手机尺寸(小于 768px)
|
||||
const isPhone = computed(() => {
|
||||
return store.isPhone
|
||||
})
|
||||
// 平板尺寸(768px ~ 991px)
|
||||
const isTablet = computed(() => {
|
||||
return store.isMobile && !store.isPhone
|
||||
})
|
||||
const themeColor = computed(() => {
|
||||
return store.themeColor
|
||||
})
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
v-if="layout === layoutEnum.CLASSICAL"
|
||||
:layout="layout"
|
||||
:isMobile="isMobile"
|
||||
:isPhone="isPhone"
|
||||
:isTablet="isTablet"
|
||||
:menuIsCollapse="menuIsCollapse"
|
||||
:sideTheme="sideTheme"
|
||||
:sysBaseConfig="sysBaseConfig"
|
||||
@@ -26,6 +28,8 @@
|
||||
v-else-if="layout === layoutEnum.DOUBLEROW"
|
||||
:layout="layout"
|
||||
:isMobile="isMobile"
|
||||
:isPhone="isPhone"
|
||||
:isTablet="isTablet"
|
||||
:sideTheme="sideTheme"
|
||||
:secondMenuSideTheme="secondMenuSideTheme"
|
||||
:sysBaseConfig="sysBaseConfig"
|
||||
@@ -60,6 +64,8 @@
|
||||
:footerCopyrightOpen="footerCopyrightOpen"
|
||||
:sideTheme="sideTheme"
|
||||
:isMobile="isMobile"
|
||||
:isPhone="isPhone"
|
||||
:isTablet="isTablet"
|
||||
:kStore="kStore"
|
||||
:layoutTagsOpen="layoutTagsOpen"
|
||||
@switchModule="switchModule"
|
||||
@@ -117,6 +123,14 @@
|
||||
const isMobile = computed(() => {
|
||||
return store.isMobile
|
||||
})
|
||||
// 手机尺寸(小于 768px)
|
||||
const isPhone = computed(() => {
|
||||
return store.isPhone
|
||||
})
|
||||
// 平板尺寸(768px ~ 991px),介于手机与桌面之间
|
||||
const isTablet = computed(() => {
|
||||
return store.isMobile && !store.isPhone
|
||||
})
|
||||
const menuIsCollapse = computed(() => {
|
||||
return store.menuIsCollapse
|
||||
})
|
||||
@@ -330,9 +344,15 @@
|
||||
const menuNavList = menu.value
|
||||
menuList.value = menuNavList
|
||||
nextTick(() => {
|
||||
const topHeaderMenuDom = document.querySelector('#topHeaderMenu')
|
||||
const lineNavDom = document.querySelector('#xn-line-nav')
|
||||
// 手机尺寸下顶栏横向菜单不渲染,无需计算折叠数量
|
||||
if (!topHeaderMenuDom || !lineNavDom) {
|
||||
return
|
||||
}
|
||||
// 获取所有的导航菜单
|
||||
let liArr = document.querySelector('#topHeaderMenu').querySelectorAll('li')
|
||||
let allWidth = document.querySelector('#xn-line-nav').offsetWidth // 可以显示区域的宽度
|
||||
let liArr = topHeaderMenuDom.querySelectorAll('li')
|
||||
let allWidth = lineNavDom.offsetWidth // 可以显示区域的宽度
|
||||
|
||||
// 计算显示的宽度
|
||||
let num = 0
|
||||
@@ -413,6 +433,13 @@
|
||||
}
|
||||
})
|
||||
})
|
||||
// 手机与非手机尺寸互相切换时,顶栏横向菜单会销毁或重建,需要重算顶栏样式与折叠数量
|
||||
watch(isPhone, () => {
|
||||
nextTick(() => {
|
||||
settingTopHeaderThemeOrColor(theme.value, layout.value)
|
||||
getNav()
|
||||
})
|
||||
})
|
||||
watch(topHeaderThemeColorOpen, () => {
|
||||
switchoverTopHeaderThemeColor()
|
||||
})
|
||||
@@ -439,11 +466,11 @@
|
||||
const topHeaderMenu = document.getElementById('topHeaderMenu')
|
||||
if (layout.value === layoutEnum.TOP) {
|
||||
if (newValue) {
|
||||
header.classList.add('top-snowy-header-layout')
|
||||
topHeaderMenu.classList.add('top-snowy-header-layout')
|
||||
header?.classList.add('top-snowy-header-layout')
|
||||
topHeaderMenu?.classList.add('top-snowy-header-layout')
|
||||
} else {
|
||||
header.classList.remove('top-snowy-header-layout')
|
||||
topHeaderMenu.classList.remove('top-snowy-header-layout')
|
||||
header?.classList.remove('top-snowy-header-layout')
|
||||
topHeaderMenu?.classList.remove('top-snowy-header-layout')
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -475,27 +502,27 @@
|
||||
|
||||
if (topHeaderThemeColorOpen.value && layout === layoutEnum.TOP) {
|
||||
nextTick(() => {
|
||||
topHeaderMenu.classList.add('top-snowy-header-layout')
|
||||
header.classList.add('top-snowy-header-layout')
|
||||
topHeaderMenu?.classList.add('top-snowy-header-layout')
|
||||
header?.classList.add('top-snowy-header-layout')
|
||||
})
|
||||
} else if (!topHeaderThemeColorOpen.value && layout === layoutEnum.TOP) {
|
||||
nextTick(() => {
|
||||
topHeaderMenu.classList.remove('top-snowy-header-layout')
|
||||
header.classList.remove('top-snowy-header-layout')
|
||||
topHeaderMenu?.classList.remove('top-snowy-header-layout')
|
||||
header?.classList.remove('top-snowy-header-layout')
|
||||
})
|
||||
}
|
||||
if (theme === themeEnum.LIGHT && layout === layoutEnum.TOP) {
|
||||
header.classList.remove('top-snowy-header')
|
||||
header.classList.add('top-snowy-header-light')
|
||||
header?.classList.remove('top-snowy-header')
|
||||
header?.classList.add('top-snowy-header-light')
|
||||
} else {
|
||||
header.classList.remove('top-snowy-header-light')
|
||||
header?.classList.remove('top-snowy-header-light')
|
||||
if (layout === layoutEnum.TOP) {
|
||||
header.classList.add('top-snowy-header')
|
||||
header?.classList.add('top-snowy-header')
|
||||
} else {
|
||||
if (theme === themeEnum.REAL_DARK) {
|
||||
header.classList.add('top-snowy-header')
|
||||
header?.classList.add('top-snowy-header')
|
||||
} else {
|
||||
header.classList.remove('top-snowy-header')
|
||||
header?.classList.remove('top-snowy-header')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,6 +648,7 @@
|
||||
const onLayoutResize = () => {
|
||||
const clientWidth = document.body.clientWidth
|
||||
store.setIsMobile(clientWidth < 992)
|
||||
store.setIsPhone(clientWidth < 768)
|
||||
}
|
||||
// 切换应用
|
||||
const switchModule = (id) => {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<a-layout>
|
||||
<a-layout-sider
|
||||
v-if="!isMobile"
|
||||
:collapsed="menuIsCollapse"
|
||||
v-if="!isPhone"
|
||||
:collapsed="sideCollapsed"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
:theme="sideTheme"
|
||||
@@ -13,11 +13,13 @@
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
<img class="logo" :src="sysBaseConfig.SNOWY_SYS_LOGO" />
|
||||
<span>{{ sysBaseConfig.SNOWY_SYS_NAME }}</span>
|
||||
<span :style="{ fontSize: sysNameFontSize }" :title="sysBaseConfig.SNOWY_SYS_NAME">{{
|
||||
sysBaseConfig.SNOWY_SYS_NAME
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
<div :class="menuIsCollapse ? 'admin-ui-side isCollapse' : 'admin-ui-side'">
|
||||
<div :class="sideCollapsed ? 'admin-ui-side isCollapse' : 'admin-ui-side'">
|
||||
<div class="admin-ui-side-scroll">
|
||||
<a-menu
|
||||
:openKeys="openKeys"
|
||||
@@ -34,13 +36,13 @@
|
||||
</div>
|
||||
</a-layout-sider>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" v-show="displayLayout" />
|
||||
<Side-m v-if="isPhone" v-show="displayLayout" />
|
||||
<!-- 右侧布局 -->
|
||||
<a-layout>
|
||||
<div id="snowyHeader" class="snowy-header" v-show="displayLayout">
|
||||
<div class="snowy-header-left xn-pl0">
|
||||
<div v-if="!isMobile" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
|
||||
<MenuUnfoldOutlined v-if="menuIsCollapse" />
|
||||
<div v-if="!isPhone" class="panel-item hidden-sm-and-down" @click="menuIsCollapseClick">
|
||||
<MenuUnfoldOutlined v-if="sideCollapsed" />
|
||||
<MenuFoldOutlined v-else />
|
||||
</div>
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" />
|
||||
@@ -92,7 +94,9 @@
|
||||
|
||||
const props = defineProps({
|
||||
layout: { type: String }, // 布局信息
|
||||
isMobile: { type: Boolean }, // 是否移动端
|
||||
isMobile: { type: Boolean }, // 是否移动端(窄屏,含平板与手机)
|
||||
isPhone: { type: Boolean }, // 是否手机尺寸(小于 768px)
|
||||
isTablet: { type: Boolean }, // 是否平板尺寸(768px ~ 991px)
|
||||
menuIsCollapse: { type: Boolean }, // 菜单是否折叠
|
||||
sideTheme: { type: String },
|
||||
sysBaseConfig: { type: Object },
|
||||
@@ -106,6 +110,43 @@
|
||||
moduleMenuShow: { type: Boolean }
|
||||
})
|
||||
const emit = defineEmits(['onSelect', 'onOpenChange', 'switchModule', 'menuIsCollapseClick', 'displayLayoutChange'])
|
||||
// 系统名称的视觉宽度权重:中文与全角符号按一个字宽计,英文数字按约六成字宽计
|
||||
const sysNameWeight = computed(() => {
|
||||
const sysName = props.sysBaseConfig ? props.sysBaseConfig.SNOWY_SYS_NAME || '' : ''
|
||||
let weight = 0
|
||||
for (const word of sysName) {
|
||||
weight += /[一-龥-]/.test(word) ? 1 : 0.6
|
||||
}
|
||||
return weight
|
||||
})
|
||||
// 系统名称字号按长度分档,避免长名称顶到侧边栏右边缘造成左右留白失衡
|
||||
const sysNameFontSize = computed(() => {
|
||||
const weight = sysNameWeight.value
|
||||
if (weight <= 6) {
|
||||
return '20px'
|
||||
}
|
||||
if (weight <= 8) {
|
||||
return '17px'
|
||||
}
|
||||
if (weight <= 10) {
|
||||
return '14px'
|
||||
}
|
||||
return '13px'
|
||||
})
|
||||
// 平板尺寸下侧边菜单默认收成图标栏,给内容区让出横向空间
|
||||
const tabletSideCollapse = ref(true)
|
||||
const sideCollapsed = computed(() => {
|
||||
return props.isTablet ? tabletSideCollapse.value : props.menuIsCollapse
|
||||
})
|
||||
// 每次进入平板尺寸都重新收起,避免沿用上一次在平板下手动展开的状态
|
||||
watch(
|
||||
() => props.isTablet,
|
||||
(newValue) => {
|
||||
if (newValue) {
|
||||
tabletSideCollapse.value = true
|
||||
}
|
||||
}
|
||||
)
|
||||
const displayLayout = ref(true)
|
||||
const route = useRoute()
|
||||
watch(route, () => {
|
||||
@@ -144,6 +185,11 @@
|
||||
emit('switchModule', id)
|
||||
}
|
||||
const menuIsCollapseClick = () => {
|
||||
// 平板尺寸下折叠状态仅本地生效,不写入用户的全局菜单折叠配置
|
||||
if (props.isTablet) {
|
||||
tabletSideCollapse.value = !tabletSideCollapse.value
|
||||
return
|
||||
}
|
||||
emit('menuIsCollapseClick')
|
||||
}
|
||||
</script>
|
||||
@@ -190,6 +236,34 @@
|
||||
.main-content-wrapper-max {
|
||||
padding: 0;
|
||||
}
|
||||
/* 系统名称区:logo 与名称整组水平居中,左右留白自动对称 */
|
||||
.snowy-header-logo {
|
||||
justify-content: center;
|
||||
padding: 0 10px;
|
||||
}
|
||||
/* 清掉出厂的 20px 左内边距,否则整组会被顶得右偏 */
|
||||
.snowy-header-logo .snowy-header-left {
|
||||
padding-left: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
.snowy-header-logo .logo-bar {
|
||||
min-width: 0;
|
||||
}
|
||||
.snowy-header-logo .logo-bar .logo {
|
||||
flex-shrink: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
/* 字号已按字数分档,这里再兜一层省略号,超长时可悬停看全称 */
|
||||
.snowy-header-logo .logo-bar > span {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
/* 侧边栏折叠后名称已隐藏,清掉它预留的右间距,让 logo 正居中 */
|
||||
.ant-layout-sider-collapsed .snowy-header-logo .logo-bar .logo {
|
||||
margin-right: 0;
|
||||
}
|
||||
.no-radius-menu :deep(.ant-menu-item),
|
||||
.no-radius-menu :deep(.ant-menu-submenu-title) {
|
||||
border-radius: 0 !important;
|
||||
|
||||
@@ -1,6 +1,14 @@
|
||||
<template>
|
||||
<a-layout>
|
||||
<a-layout-sider v-if="!isMobile" width="80" :theme="sideTheme" :trigger="null" collapsible v-show="displayLayout">
|
||||
<a-layout-sider
|
||||
v-if="!isPhone"
|
||||
:width="firstSideWidth"
|
||||
:class="{ 'doublerow-first-side-tablet': isTablet }"
|
||||
:theme="sideTheme"
|
||||
:trigger="null"
|
||||
collapsible
|
||||
v-show="displayLayout"
|
||||
>
|
||||
<header id="snowyHeaderLogo" class="snowy-header-logo">
|
||||
<div class="snowy-header-left">
|
||||
<div class="logo-bar">
|
||||
@@ -32,9 +40,13 @@
|
||||
>
|
||||
<a v-if="item.meta && item.meta.type === 'link'" :href="item.path" target="_blank" @click.stop="() => {}" />
|
||||
<template #icon>
|
||||
<component :is="item.meta.icon" class="xn-pl10" />
|
||||
<!-- 平板尺寸下只留图标,模块名改由右侧气泡提示承载 -->
|
||||
<a-tooltip v-if="isTablet" placement="right" :title="item.meta.title">
|
||||
<component :is="item.meta.icon" />
|
||||
</a-tooltip>
|
||||
<component v-else :is="item.meta.icon" class="xn-pl10" />
|
||||
</template>
|
||||
<div class="snowy-doublerow-layout-menu-item-fort-div">
|
||||
<div v-if="!isTablet" class="snowy-doublerow-layout-menu-item-fort-div">
|
||||
<span class="snowy-doublerow-layout-menu-item-fort-div-span">
|
||||
{{ item.meta.title }}
|
||||
</span>
|
||||
@@ -43,7 +55,7 @@
|
||||
</a-menu>
|
||||
</a-layout-sider>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" v-show="displayLayout" />
|
||||
<Side-m v-if="isPhone" v-show="displayLayout" />
|
||||
<a-layout>
|
||||
<div id="snowyHeader" class="snowy-header" v-show="displayLayout">
|
||||
<div class="snowy-header-left xn-pl0">
|
||||
@@ -56,16 +68,16 @@
|
||||
<a-layout>
|
||||
<div v-show="displayLayout"></div>
|
||||
<a-layout-sider
|
||||
v-if="!isMobile"
|
||||
v-if="!isPhone"
|
||||
v-show="displayLayout && layoutSiderDowbleMenu"
|
||||
:collapsed="menuIsCollapse"
|
||||
:collapsed="secondSideCollapsed"
|
||||
:trigger="null"
|
||||
width="170"
|
||||
collapsible
|
||||
:theme="secondMenuSideTheme"
|
||||
>
|
||||
<a-menu
|
||||
:collapsed="menuIsCollapse"
|
||||
:collapsed="secondSideCollapsed"
|
||||
:openKeys="openKeys"
|
||||
:selectedKeys="selectedKeys"
|
||||
mode="inline"
|
||||
@@ -112,7 +124,9 @@
|
||||
|
||||
const props = defineProps({
|
||||
layout: { type: String }, // 布局信息
|
||||
isMobile: { type: Boolean }, // 是否移动端
|
||||
isMobile: { type: Boolean }, // 是否移动端(窄屏,含平板与手机)
|
||||
isPhone: { type: Boolean }, // 是否手机尺寸(小于 768px)
|
||||
isTablet: { type: Boolean }, // 是否平板尺寸(768px ~ 991px)
|
||||
sideTheme: { type: String },
|
||||
menuIsCollapse: {},
|
||||
sysBaseConfig: { type: Object },
|
||||
@@ -129,6 +143,14 @@
|
||||
moduleMenuShow: { type: Boolean },
|
||||
secondMenuSideTheme: {}
|
||||
})
|
||||
// 平板尺寸下一级目录栏收成纯图标栏,桌面保持出厂的 80
|
||||
const firstSideWidth = computed(() => {
|
||||
return props.isTablet ? 56 : 80
|
||||
})
|
||||
// 平板尺寸下二级菜单收成图标栏,避免两排侧边栏占去内容区过多横向空间
|
||||
const secondSideCollapsed = computed(() => {
|
||||
return props.isTablet ? true : props.menuIsCollapse
|
||||
})
|
||||
const emit = defineEmits(['onSelect', 'switchModule', 'showMenu', 'displayLayoutChange'])
|
||||
const displayLayout = ref(true)
|
||||
const route = useRoute()
|
||||
@@ -211,4 +233,25 @@
|
||||
.main-content-wrapper-max {
|
||||
padding: 0;
|
||||
}
|
||||
/* 平板尺寸下第一排收成纯图标栏:logo 居中,菜单项去掉左右内边距让图标居中并放大 */
|
||||
.doublerow-first-side-tablet {
|
||||
:deep(.snowy-header-logo) {
|
||||
justify-content: center;
|
||||
}
|
||||
/* 清掉 snowy-header-left 的 20px 左内边距,否则 logo 会被顶得右偏 */
|
||||
:deep(.snowy-header-logo .snowy-header-left) {
|
||||
padding-left: 0;
|
||||
}
|
||||
:deep(.snowy-header-logo .logo-bar .logo) {
|
||||
margin-right: 0;
|
||||
}
|
||||
:deep(.ant-menu-item .ant-menu-item-icon) {
|
||||
font-size: 18px;
|
||||
margin-inline-end: 0 !important;
|
||||
}
|
||||
/* 标题已隐藏,清掉图标与标题之间的预留间距,否则图标会左偏 */
|
||||
:deep(.ant-menu-item .ant-menu-item-icon + span) {
|
||||
margin-inline-start: 0 !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -13,7 +13,8 @@
|
||||
</header>
|
||||
</div>
|
||||
<moduleMenu v-if="moduleMenuShow" @switchModule="switchModule" class="xn-pdl25" />
|
||||
<div class="xn-navmenu-line" id="xn-line-nav">
|
||||
<!-- 手机尺寸下顶栏放不下横向目录菜单,改由左下角悬浮按钮的抽屉菜单承载 -->
|
||||
<div class="xn-navmenu-line" id="xn-line-nav" v-if="!isPhone">
|
||||
<a-menu
|
||||
class="xn-bb0"
|
||||
id="topHeaderMenu"
|
||||
@@ -32,7 +33,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<!-- 手机端情况下的左侧菜单 -->
|
||||
<Side-m v-if="isMobile" v-show="displayLayout" />
|
||||
<Side-m v-if="isPhone" v-show="displayLayout" />
|
||||
<breadcrumb v-if="!isMobile && breadcrumbOpen" v-show="displayLayout" />
|
||||
<!-- 多标签 -->
|
||||
<Tags v-if="!isMobile && layoutTagsOpen" v-show="displayLayout" />
|
||||
@@ -76,7 +77,9 @@
|
||||
selectedKeys: { type: Array },
|
||||
openKeys: { type: Array },
|
||||
sideTheme: { type: String },
|
||||
isMobile: { type: Boolean }, // 是否移动端
|
||||
isMobile: { type: Boolean }, // 是否移动端(窄屏,含平板与手机)
|
||||
isPhone: { type: Boolean }, // 是否手机尺寸(小于 768px)
|
||||
isTablet: { type: Boolean }, // 是否平板尺寸(768px ~ 991px)
|
||||
breadcrumbOpen: { type: Boolean }, //面包屑
|
||||
layoutTagsOpen: { type: Boolean },
|
||||
layoutSiderDowbleMenu: { type: Boolean },
|
||||
@@ -157,6 +160,12 @@
|
||||
.xn-pd050 {
|
||||
padding: 0 50px;
|
||||
}
|
||||
/* 手机尺寸下顶栏两侧留白收窄,避免 logo 与用户栏被挤压 */
|
||||
@media (max-width: 767px) {
|
||||
.xn-pd050 {
|
||||
padding: 0 10px;
|
||||
}
|
||||
}
|
||||
.xn-pl10 {
|
||||
padding-left: 10px;
|
||||
}
|
||||
|
||||
@@ -28,8 +28,10 @@ const getCacheConfig = (value) => {
|
||||
|
||||
// deprecated 请使用 useGlobalStore
|
||||
export const globalStore = defineStore('global', () => {
|
||||
// 移动端布局
|
||||
// 移动端布局(窄屏,小于 992px,含平板与手机)
|
||||
const isMobile = ref(false)
|
||||
// 手机布局(小于 768px),平板尺寸为 isMobile 为真但 isPhone 为假
|
||||
const isPhone = ref(false)
|
||||
// 布局
|
||||
const layout = ref(getCacheConfig('SNOWY_LAYOUT'))
|
||||
// 菜单是否折叠 toggle
|
||||
@@ -77,6 +79,9 @@ export const globalStore = defineStore('global', () => {
|
||||
const setIsMobile = (key) => {
|
||||
isMobile.value = key
|
||||
}
|
||||
const setIsPhone = (key) => {
|
||||
isPhone.value = key
|
||||
}
|
||||
const setIsLocked = (key) => {
|
||||
isLocked.value = key
|
||||
tool.data.set('SNOWY_IS_LOCKED', key)
|
||||
@@ -161,6 +166,7 @@ export const globalStore = defineStore('global', () => {
|
||||
}
|
||||
return {
|
||||
isMobile,
|
||||
isPhone,
|
||||
layout,
|
||||
menuIsCollapse,
|
||||
sideUniqueOpen,
|
||||
@@ -183,6 +189,7 @@ export const globalStore = defineStore('global', () => {
|
||||
isLocked,
|
||||
autoLockTime,
|
||||
setIsMobile,
|
||||
setIsPhone,
|
||||
setIsLocked,
|
||||
setAutoLockTime,
|
||||
setLayout,
|
||||
|
||||
Reference in New Issue
Block a user