perf: 优化移动端布局

This commit is contained in:
kuaifan 2025-04-09 19:12:12 +08:00
parent da7dc477c8
commit bc417b9eea
10 changed files with 102 additions and 61 deletions

View File

@ -1,7 +1,7 @@
<template>
<div id="app">
<div id="app" class="app-view" :style="appStyle">
<keep-alive>
<router-view class="child-view" @hook:mounted.once="onRouterViewMounted"></router-view>
<router-view class="child-view" :style="childStyle" @hook:mounted.once="onRouterViewMounted"></router-view>
</keep-alive>
<!--任务操作-->
@ -30,15 +30,31 @@
<!--引导页-->
<GuidePage/>
<!--返回效果-->
<MobileBack/>
<!--移动端通知-->
<MobileNotification/>
</div>
</template>
<style lang="scss" scoped>
.app-view {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
.child-view {
position: absolute;
width: 100%;
min-height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
will-change: transform;
transition: all .3s cubic-bezier(.55, 0, .1, 1);
}
</style>
@ -51,6 +67,8 @@ import NetworkException from "./components/NetworkException";
import GuidePage from "./components/GuidePage";
import TaskOperation from "./pages/manage/components/TaskOperation";
import MeetingManager from "./pages/manage/components/MeetingManager";
import MobileNotification from "./components/Mobile/Notification.vue";
import MobileBack from "./components/Mobile/Back.vue";
import DropdownMenu from "./components/DropdownMenu";
import {ctrlPressed} from "./mixins/ctrlPressed";
import {mapState} from "vuex";
@ -60,6 +78,7 @@ export default {
mixins: [ctrlPressed],
components: {
MobileBack, MobileNotification,
AuthException,
MeetingManager,
DropdownMenu,
@ -74,8 +93,9 @@ export default {
data() {
return {
appInter: null,
appBackgroundColor: "#f8f8f8",
countDown: Math.min(30, 60 - $A.daytz().second()),
lastCheckUpgradeYmd: $A.daytz().format('YYYY-MM-DD')
lastCheckUpgradeYmd: $A.daytz().format('YYYY-MM-DD'),
}
},
@ -95,14 +115,28 @@ export default {
},
computed: {
...mapState(['ws', 'themeConf', 'windowOrientation']),
...mapState(['ws', 'themeConf', 'windowOrientation', 'safeAreaSize']),
appStyle({appBackgroundColor}) {
return {
backgroundColor: appBackgroundColor,
}
},
childStyle({safeAreaSize}) {
return {
top: `${safeAreaSize.top}px`,
bottom: `${safeAreaSize.bottom}px`,
}
},
},
watch: {
'$route': {
handler(to) {
this.$store.state.routeName = to.name
this.$store.state.routePath = to.path
handler({name, path, params}) {
this.$store.state.routeName = name
this.$store.state.routePath = path
this.$store.state.mobileTabbar = (name === 'manage-project' && !/^\d+$/.test(params.projectId)) || ['manage-dashboard', 'manage-messenger', 'manage-application'].includes(name);
},
immediate: true,
},

View File

@ -10,12 +10,6 @@ import microApp from '@micro-zoe/micro-app'
export default {
name: "MobileBack",
props: {
showTabbar: {
type: Boolean,
default: false
},
},
data() {
return {
@ -46,7 +40,7 @@ export default {
},
computed: {
...mapState(['fileLists', 'messengerSearchKey']),
...mapState(['fileLists', 'messengerSearchKey', 'mobileTabbar']),
style() {
const offset = 135;
@ -112,7 +106,7 @@ export default {
},
canBack() {
if (!this.showTabbar) {
if (!this.mobileTabbar) {
return true;
}
if (this.$Modal.visibles().length > 0) {

View File

@ -14,6 +14,8 @@
</template>
<script>
import emitter from "../../store/events";
export default {
name: "MobileNotification",
data() {
@ -31,7 +33,12 @@ export default {
};
},
mounted() {
emitter.on('openMobileNotification', this.open);
},
beforeDestroy() {
emitter.off('openMobileNotification', this.open);
this.timer && clearTimeout(this.timer);
this.show = false;
},

View File

@ -1,5 +1,5 @@
<template>
<div class="page-manage" :class="{'show-tabbar': showMobileTabbar, 'not-logged': userId <= 0}">
<div class="page-manage" :class="pageClass">
<div class="manage-box-menu">
<Dropdown
class="page-manage-menu-dropdown main-menu"
@ -333,10 +333,8 @@
<!--移动端选项卡-->
<transition name="mobile-slide">
<MobileTabbar v-if="showMobileTabbar" @on-click="onTabbarClick"/>
<MobileTabbar v-if="mobileTabbar" @on-click="onTabbarClick"/>
</transition>
<MobileBack :showTabbar="showMobileTabbar"/>
<MobileNotification ref="mobileNotification"/>
<!-- okr明细 -->
<MicroApps v-show="false" v-if="$route.name != 'manage-apps'" name="okr-details" :url="okrUrl" :datas="okrWindow"/>
@ -357,8 +355,6 @@ import DrawerOverlay from "../components/DrawerOverlay";
import MobileTabbar from "../components/Mobile/Tabbar";
import TaskAdd from "./manage/components/TaskAdd";
import Report from "./manage/components/Report";
import MobileBack from "../components/Mobile/Back";
import MobileNotification from "../components/Mobile/Notification";
import longpress from "../directives/longpress";
import DialogModal from "./manage/components/DialogModal";
import TaskModal from "./manage/components/TaskModal";
@ -385,8 +381,6 @@ export default {
ApproveExport,
TaskModal,
DialogModal,
MobileNotification,
MobileBack,
MobileTabbar,
TaskAdd,
Report,
@ -518,12 +512,30 @@ export default {
'okrWindow',
'formOptions'
'formOptions',
'mobileTabbar'
]),
...mapGetters(['dashboardTask']),
// okr
/**
* page className
* @param mobileTabbar
* @param userId
* @returns {{"show-tabbar", "not-logged": boolean}}
*/
pageClass({mobileTabbar, userId}) {
return {
'show-tabbar': mobileTabbar,
'not-logged': userId <= 0
}
},
/**
* okr路由
* @returns {any|string}
*/
okrUrl() {
return import.meta.env.VITE_OKR_WEB_URL || $A.mainUrl("apps/okr")
},
@ -680,13 +692,6 @@ export default {
return cacheTasks.find(task => task.id === id) || {}
});
},
showMobileTabbar() {
if (this.routeName === 'manage-project' && !/^\d+$/.test(this.$route.params.projectId)) {
return true;
}
return ['manage-dashboard','manage-messenger', 'manage-application'].includes(this.routeName)
},
},
watch: {
@ -1077,14 +1082,14 @@ export default {
if (this.__notificationId === id) {
this.__notificationId = null
if (this.$isEEUiApp) {
this.$refs.mobileNotification.open({
emitter.emit('openMobileNotification', {
userid: userid,
title,
desc: body,
callback: () => {
this.$store.dispatch('openDialog', dialog_id)
}
})
});
} else if (this.$Electron) {
this.$Electron.sendMessage('openNotification', {
icon: userimg || $A.originUrl('images/logo.png'),

View File

@ -6,11 +6,6 @@
<style lang="scss" scoped>
.token-transfer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;

View File

@ -21,7 +21,7 @@ export default {
// 浏览器尺寸信息
windowWidth: windowWidth,
windowHeight: windowHeight,
safeAreaSize: {top: 0, bottom: 0, data: {}}, // 安全区域尺寸
safeAreaSize: {top: 0, bottom: 0, data: null}, // 安全区域尺寸
// 浏览器窗口方向
windowOrientation: windowOrientation,
@ -55,6 +55,9 @@ export default {
routeHistoryLast: {},
routeLoading: 0,
// 显示移动端Tabbar
mobileTabbar: false,
// 请求时间
callAt: [],

View File

@ -39,7 +39,18 @@
margin: 0;
height: 60px;
background-color: #f8f8f8;
box-shadow: 0 0 1px rgba(28, 34, 43, 0.15);
&:before {
content: "";
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
z-index: 1;
transform: scaleY(0.5);
background-color: rgba(28, 34, 43, 0.05);
}
> li {
flex: 1;
@ -354,11 +365,15 @@ body.window-portrait {
}
@media (max-height: 400px) {
.mobile-tabbar, .messenger-menu {
.mobile-tabbar {
display: none !important;
}
.page-manage.show-tabbar .manage-box-main {
margin-bottom: 0 !important;
.page-manage {
&.show-tabbar {
.manage-box-main {
margin-bottom: 0 !important;
}
}
}
}
}

View File

@ -1,9 +1,4 @@
.page-login {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
align-items: center;
justify-content: center;
@ -326,4 +321,4 @@ body.window-portrait {
}
}
}
}
}

View File

@ -1,9 +1,4 @@
.page-manage {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
display: flex;
&.not-logged {
.manage-box-menu {

View File

@ -661,7 +661,7 @@ body.window-portrait {
.page-messenger {
.messenger-wrapper {
.messenger-select {
position: fixed;
position: absolute;
top: 0;
left: 0;
width: 100%;
@ -690,9 +690,7 @@ body.window-portrait {
}
}
.messenger-menu {
border-top: 0;
height: 60px;
opacity: 0;
display: none;
}
.messenger-list {
ul {