<script setup lang="ts">
|
import { computed, onMounted, onUnmounted, ref } from 'vue';
|
import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
|
import Icon from '#/mobile/icon.vue';
|
import { allowedMobilePath } from '#/mobile/access';
|
import { saveMobileScroll } from '#/mobile/scroll';
|
import './mobile.css';
|
const route = useRoute(), router = useRouter();
|
const keyboard = ref(false);
|
const tabs = [{ key:'home', title:'工作台', icon:'home' },{key:'work', title:'作业',icon:'work'},{key:'records',title:'记录',icon:'records'},{key:'mine',title:'我的',icon:'mine'}];
|
const root = computed(() => ['home','work','records','mine'].includes(route.path.split('/')[2] || ''));
|
function updateViewport() { keyboard.value = document.activeElement?.matches('input,textarea') === true && (window.visualViewport?.height || window.innerHeight) < window.innerHeight - 120; }
|
onMounted(() => window.visualViewport?.addEventListener('resize', updateViewport));
|
onUnmounted(() => window.visualViewport?.removeEventListener('resize', updateViewport));
|
onBeforeRouteUpdate((_to,from)=>{saveMobileScroll(from.path);});
|
function back() {
|
const previous=window.history.state?.back;
|
if(typeof previous==='string'&&previous.startsWith('/mobile/')&&allowedMobilePath(previous.split('?')[0]||''))router.back();
|
else router.push('/mobile/work');
|
}
|
</script>
|
<template>
|
<div class="mobile-shell" :class="{ 'keyboard-open': keyboard }">
|
<header class="m-header">
|
<button v-if="!root" class="m-icon-button" aria-label="返回上一页" @click="back"><Icon name="back"/></button>
|
<h1>{{ route.meta.title }}</h1>
|
<span class="m-product">MOM</span>
|
</header>
|
<main class="m-content" :class="{ 'with-tabs': root && !keyboard }">
|
<RouterView v-slot="{ Component }"><KeepAlive :include="['MobileQuery','MobileStock']"><component :is="Component" :key="route.path"/></KeepAlive></RouterView>
|
</main>
|
<nav v-if="root && !keyboard" class="m-nav" aria-label="主导航">
|
<RouterLink v-for="tab in tabs.filter(t => allowedMobilePath('/mobile/' + t.key))" :key="tab.key" :to="'/mobile/' + tab.key" :aria-current="route.path.endsWith('/' + tab.key) ? 'page' : undefined">
|
<Icon :name="tab.icon"/><span>{{ tab.title }}</span>
|
</RouterLink>
|
</nav>
|
</div>
|
</template>
|