云
8 小时以前 fb4db4ae9b6a7f113ba049f6789e6916c0dcc276
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<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>