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