mirror of
https://github.com/kuaifan/dootask.git
synced 2025-12-11 18:42:54 +00:00
perf: 优化移动端布局
This commit is contained in:
parent
bc417b9eea
commit
841ed4e682
@ -1,9 +1,16 @@
|
||||
<template>
|
||||
<div id="app" class="app-view" :style="appStyle">
|
||||
<div id="app" class="app-view">
|
||||
<!--顶部状态栏-->
|
||||
<div class="child-status-bar"></div>
|
||||
|
||||
<!--主路由视图-->
|
||||
<keep-alive>
|
||||
<router-view class="child-view" :style="childStyle" @hook:mounted.once="onRouterViewMounted"></router-view>
|
||||
<router-view class="child-view" @hook:mounted.once="onRouterViewMounted"/>
|
||||
</keep-alive>
|
||||
|
||||
<!--底部导航栏-->
|
||||
<div class="child-navigation-bar"></div>
|
||||
|
||||
<!--任务操作-->
|
||||
<TaskOperation/>
|
||||
|
||||
@ -25,9 +32,6 @@
|
||||
<!--身份提示-->
|
||||
<AuthException/>
|
||||
|
||||
<!--网络提示-->
|
||||
<NetworkException v-if="windowLandscape"/>
|
||||
|
||||
<!--引导页-->
|
||||
<GuidePage/>
|
||||
|
||||
@ -36,6 +40,9 @@
|
||||
|
||||
<!--移动端通知-->
|
||||
<MobileNotification/>
|
||||
|
||||
<!--网络提示-->
|
||||
<NetworkException v-if="windowLandscape"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -47,15 +54,27 @@
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
.child-view {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
will-change: transform;
|
||||
transition: all .3s cubic-bezier(.55, 0, .1, 1);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.child-status-bar {
|
||||
flex-shrink: 0;
|
||||
height: var(--status-bar-height);
|
||||
background-color: var(--status-bar-color);
|
||||
}
|
||||
|
||||
.child-navigation-bar {
|
||||
flex-shrink: 0;
|
||||
height: var(--navigation-bar-height);
|
||||
background-color: var(--navigation-bar-color);
|
||||
}
|
||||
|
||||
.child-view {
|
||||
flex: 1;
|
||||
height: 0;
|
||||
will-change: transform;
|
||||
transition: all .3s cubic-bezier(.55, 0, .1, 1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
@ -78,7 +97,8 @@ export default {
|
||||
mixins: [ctrlPressed],
|
||||
|
||||
components: {
|
||||
MobileBack, MobileNotification,
|
||||
MobileBack,
|
||||
MobileNotification,
|
||||
AuthException,
|
||||
MeetingManager,
|
||||
DropdownMenu,
|
||||
@ -93,7 +113,6 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
appInter: null,
|
||||
appBackgroundColor: "#f8f8f8",
|
||||
countDown: Math.min(30, 60 - $A.daytz().second()),
|
||||
lastCheckUpgradeYmd: $A.daytz().format('YYYY-MM-DD'),
|
||||
}
|
||||
@ -115,18 +134,31 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
...mapState(['ws', 'themeConf', 'windowOrientation', 'safeAreaSize']),
|
||||
...mapState(['ws', 'themeConf', 'windowOrientation', 'safeAreaSize', 'mobileTabbar']),
|
||||
|
||||
appStyle({appBackgroundColor}) {
|
||||
return {
|
||||
backgroundColor: appBackgroundColor,
|
||||
statusColor({routeName}) {
|
||||
if (!routeName) {
|
||||
return null
|
||||
}
|
||||
if (['manage-messenger', 'manage-project'].includes(routeName)) {
|
||||
return '#f8f8f8'
|
||||
}
|
||||
if (routeName.startsWith('manage-setting')) {
|
||||
return '#f8f8f8'
|
||||
}
|
||||
return null
|
||||
},
|
||||
|
||||
childStyle({safeAreaSize}) {
|
||||
navigationColor({statusColor, mobileTabbar}) {
|
||||
return statusColor || (mobileTabbar ? '#f8f8f8' : null)
|
||||
},
|
||||
|
||||
rootStyle() {
|
||||
return {
|
||||
top: `${safeAreaSize.top}px`,
|
||||
bottom: `${safeAreaSize.bottom}px`,
|
||||
'--status-bar-height': `${this.safeAreaSize.top}px`,
|
||||
'--status-bar-color': this.statusColor || '#ffffff',
|
||||
'--navigation-bar-height': `${this.safeAreaSize.bottom}px`,
|
||||
'--navigation-bar-color': this.navigationColor || '#ffffff',
|
||||
}
|
||||
},
|
||||
},
|
||||
@ -183,6 +215,15 @@ export default {
|
||||
immediate: true
|
||||
},
|
||||
|
||||
rootStyle: {
|
||||
handler(style) {
|
||||
for (const key in style) {
|
||||
document.documentElement.style.setProperty(key, style[key])
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
|
||||
windowTouch: {
|
||||
handler(support) {
|
||||
if (support) {
|
||||
@ -625,9 +666,9 @@ export default {
|
||||
if (!$A.isJson(event)) {
|
||||
return;
|
||||
}
|
||||
this.$store.state.keyboardType = event.keyboardType;
|
||||
this.$store.state.keyboardShow = event.keyboardType === 'show';
|
||||
this.$store.state.keyboardHeight = event.keyboardHeight;
|
||||
$A.eeuiAppShakeToEditEnabled(this.$store.state.keyboardType === 'show')
|
||||
$A.eeuiAppShakeToEditEnabled(this.$store.state.keyboardShow)
|
||||
}
|
||||
// 通知权限
|
||||
window.__onNotificationPermissionStatus = (ret) => {
|
||||
|
||||
19
resources/assets/js/app.js
vendored
19
resources/assets/js/app.js
vendored
@ -338,14 +338,17 @@ const $preload = async () => {
|
||||
}
|
||||
return
|
||||
}
|
||||
$A.eeuiAppGetSafeAreaInsets().then(data => {
|
||||
const proportion = data.height / window.outerHeight
|
||||
store.state.safeAreaSize = {
|
||||
top: Math.round(data.top / proportion * 100) / 100,
|
||||
bottom: Math.round(data.bottom / proportion * 100) / 100,
|
||||
data
|
||||
}
|
||||
}).catch(console.warn)
|
||||
const pageInfo = $A.eeuiAppGetPageInfo() || {};
|
||||
if (pageInfo.pageName === 'firstPage') {
|
||||
$A.eeuiAppGetSafeAreaInsets().then(data => {
|
||||
const proportion = data.height / window.outerHeight
|
||||
store.state.safeAreaSize = {
|
||||
top: Math.round(data.top / proportion * 100) / 100,
|
||||
bottom: Math.round(data.bottom / proportion * 100) / 100,
|
||||
data
|
||||
}
|
||||
}).catch(console.warn)
|
||||
}
|
||||
}
|
||||
|
||||
await store.dispatch("preload");
|
||||
|
||||
@ -85,7 +85,9 @@ export default {
|
||||
const pageX = event.type === 'touchmove' ? event.targetTouches[0].pageX : event.pageX;
|
||||
const pageY = event.type === 'touchmove' ? event.targetTouches[0].pageY : event.pageY;
|
||||
if (typeof this.isScrolling === 'undefined') {
|
||||
this.isScrolling = !!(this.isScrolling || Math.abs(pageY - this.touchesStart.y) > Math.abs(pageX - this.touchesStart.x));
|
||||
const verticalMove = Math.abs(pageY - this.touchesStart.y);
|
||||
const horizontalMove = Math.abs(pageX - this.touchesStart.x) * 1.5; // 可调整的阈值
|
||||
this.isScrolling = verticalMove > horizontalMove;
|
||||
}
|
||||
if (this.isScrolling) {
|
||||
this.isTouched = false;
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
|
||||
<script>
|
||||
import emitter from "../../store/events";
|
||||
import {mapState} from "vuex";
|
||||
|
||||
export default {
|
||||
name: "MobileNotification",
|
||||
@ -44,9 +45,11 @@ export default {
|
||||
},
|
||||
|
||||
computed: {
|
||||
notifyStyle() {
|
||||
...mapState(['safeAreaSize']),
|
||||
|
||||
notifyStyle({windowScrollY, safeAreaSize}) {
|
||||
return {
|
||||
marginTop: this.$store.state.windowScrollY + 'px',
|
||||
marginTop: (windowScrollY + safeAreaSize.top) + 'px',
|
||||
};
|
||||
},
|
||||
},
|
||||
@ -64,7 +67,7 @@ export default {
|
||||
this.show = true;
|
||||
this.timer && clearTimeout(this.timer);
|
||||
if (this.duration > 0) {
|
||||
this.timer = setTimeout(this.close, this.duration)
|
||||
// this.timer = setTimeout(this.close, this.duration)
|
||||
}
|
||||
$A.eeuiAppSendMessage({
|
||||
action: 'setVibrate',
|
||||
|
||||
@ -143,7 +143,7 @@ export default {
|
||||
computed: {
|
||||
...mapState([
|
||||
'themeName',
|
||||
'keyboardType'
|
||||
'keyboardShow'
|
||||
]),
|
||||
|
||||
isFullscreen({windowWidth}) {
|
||||
@ -248,7 +248,7 @@ export default {
|
||||
},
|
||||
|
||||
onTouchstart() {
|
||||
if (this.keyboardType === "show") {
|
||||
if (this.keyboardShow) {
|
||||
$A.eeuiAppKeyboardHide();
|
||||
}
|
||||
},
|
||||
|
||||
2
resources/assets/js/functions/eeui.js
vendored
2
resources/assets/js/functions/eeui.js
vendored
@ -61,7 +61,7 @@
|
||||
|
||||
// 获取页面信息
|
||||
eeuiAppGetPageInfo(pageName) {
|
||||
return this.eeuiModule()?.getPageInfo(pageName);
|
||||
return this.eeuiModule()?.getPageInfo(pageName || "");
|
||||
},
|
||||
|
||||
// 打开app新页面
|
||||
|
||||
@ -559,9 +559,10 @@ export default {
|
||||
|
||||
'cacheTranscriptionLanguage',
|
||||
'cacheKeyboard',
|
||||
'keyboardType',
|
||||
'keyboardShow',
|
||||
'keyboardHeight',
|
||||
'isModKey',
|
||||
'safeAreaSize',
|
||||
]),
|
||||
|
||||
...mapGetters(['getDialogDraft', 'getDialogQuote']),
|
||||
@ -613,8 +614,8 @@ export default {
|
||||
},
|
||||
|
||||
recordConvertFooterStyle() {
|
||||
const {recordConvertFocus, keyboardType, keyboardHeight} = this;
|
||||
return (recordConvertFocus && keyboardType === 'show' && keyboardHeight > 120) ? {
|
||||
const {recordConvertFocus, keyboardShow, keyboardHeight} = this;
|
||||
return (recordConvertFocus && keyboardShow && keyboardHeight > 120) ? {
|
||||
alignItems: 'flex-start',
|
||||
transform: 'translateY(12px)'
|
||||
} : {}
|
||||
@ -719,10 +720,12 @@ export default {
|
||||
return this.getDialogQuote(this.dialogId)?.type === 'update'
|
||||
},
|
||||
|
||||
chatInputBoxStyle({iOSDevices, fullInput, viewportHeight}) {
|
||||
chatInputBoxStyle({iOSDevices, fullInput, keyboardShow, viewportHeight, safeAreaSize}) {
|
||||
const style = {}
|
||||
if (iOSDevices && fullInput && viewportHeight > 0) {
|
||||
style.height = Math.max(100, viewportHeight - 70) + 'px'
|
||||
if (iOSDevices && fullInput && keyboardShow && viewportHeight > 0) {
|
||||
style.height = Math.max(100, viewportHeight - 70 - safeAreaSize.top) + 'px'
|
||||
} else {
|
||||
style.paddingBottom = `${safeAreaSize.bottom}px`
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
4
resources/assets/js/store/state.js
vendored
4
resources/assets/js/store/state.js
vendored
@ -36,8 +36,8 @@ export default {
|
||||
},
|
||||
|
||||
// 键盘状态(仅iOS)
|
||||
keyboardType: null, // show|hide
|
||||
keyboardHeight: 0, // 键盘高度
|
||||
keyboardShow: false, // 键盘可见
|
||||
keyboardHeight: 0, // 键盘高度
|
||||
|
||||
// 是否按下Ctrl/Command键
|
||||
isModKey: false,
|
||||
|
||||
1
resources/assets/sass/app.scss
vendored
1
resources/assets/sass/app.scss
vendored
@ -1,4 +1,5 @@
|
||||
@import "var";
|
||||
@import "root";
|
||||
@import "fileicon";
|
||||
@import "element";
|
||||
@import "fonts-ft";
|
||||
|
||||
@ -6,7 +6,8 @@
|
||||
max-width: none;
|
||||
|
||||
.ivu-modal-content {
|
||||
margin-top: 46px;
|
||||
margin-top: calc(var(--status-bar-height) + 46px);
|
||||
margin-bottom: 0;
|
||||
border-top-left-radius: 18px !important;
|
||||
border-top-right-radius: 18px !important;
|
||||
|
||||
@ -16,6 +17,7 @@
|
||||
|
||||
.search-list {
|
||||
max-height: none;
|
||||
padding-bottom: var(--navigation-bar-height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,7 +455,8 @@
|
||||
max-width: none;
|
||||
|
||||
.ivu-modal-content {
|
||||
margin-top: 46px;
|
||||
margin-top: calc(var(--status-bar-height) + 46px);
|
||||
margin-bottom: 0;
|
||||
border-top-left-radius: 18px !important;
|
||||
border-top-right-radius: 18px !important;
|
||||
}
|
||||
@ -477,7 +478,7 @@
|
||||
max-height: none;
|
||||
|
||||
ul {
|
||||
padding-bottom: 0;
|
||||
padding-bottom: var(--navigation-bar-height);
|
||||
|
||||
> li {
|
||||
&:last-child {
|
||||
|
||||
6
resources/assets/sass/pages/common.scss
vendored
6
resources/assets/sass/pages/common.scss
vendored
@ -279,6 +279,10 @@ body {
|
||||
.ivu-modal {
|
||||
top: 100px;
|
||||
padding-bottom: 100px;
|
||||
@media (max-width: 768px) {
|
||||
top: 60px;
|
||||
padding-bottom: 60px;
|
||||
}
|
||||
@media (max-height: 900px) {
|
||||
top: 35px;
|
||||
padding-bottom: 35px;
|
||||
@ -364,6 +368,8 @@ body {
|
||||
|
||||
.ivu-modal-content {
|
||||
border-radius: 18px;
|
||||
margin-top: var(--status-bar-height);
|
||||
margin-bottom: var(--navigation-bar-height);
|
||||
|
||||
.ivu-modal-close {
|
||||
.ivu-icon-ios-close {
|
||||
|
||||
@ -988,7 +988,8 @@
|
||||
.chat-input-full-input {
|
||||
.ivu-modal {
|
||||
.ivu-modal-content {
|
||||
margin-top: 46px;
|
||||
margin-top: calc(var(--status-bar-height) + 46px) !important;
|
||||
margin-bottom: 0 !important;
|
||||
border-top-left-radius: 18px !important;
|
||||
border-top-right-radius: 18px !important;
|
||||
.ivu-modal-body {
|
||||
|
||||
@ -71,7 +71,7 @@ body.window-portrait {
|
||||
}
|
||||
}
|
||||
.calendar-box {
|
||||
padding: 0 24px 5px;
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
6
resources/assets/sass/root.scss
vendored
Normal file
6
resources/assets/sass/root.scss
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
:root {
|
||||
--status-bar-height: 0px;
|
||||
--status-bar-color: #ffffff;
|
||||
--navigation-bar-height: 0px;
|
||||
--navigation-bar-color: #ffffff;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user