74 lines
2.1 KiB
Vue
74 lines
2.1 KiB
Vue
<template>
|
|
<main class="m-app" :class="{ 'm-app--with-nav': showNav }">
|
|
<router-view />
|
|
<nav v-if="showNav" class="m-bottom-nav" aria-label="主要导航">
|
|
<router-link v-for="item in nav" :key="item.path" :to="item.path" :aria-label="item.label">
|
|
<img :src="isActive(item.path) ? item.activeIcon : item.icon" alt="" />
|
|
<span>{{ item.label }}</span>
|
|
</router-link>
|
|
</nav>
|
|
</main>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { computed, watch } from 'vue';
|
|
import { useRoute, useRouter } from 'vue-router';
|
|
import { hasSession } from './api';
|
|
import { mobileAssets } from './assets';
|
|
|
|
const route = useRoute();
|
|
const router = useRouter();
|
|
const showNav = computed(() => Boolean(route.meta.mobileNav));
|
|
const nav = [
|
|
{
|
|
label: '首页',
|
|
path: '/app/home',
|
|
icon: mobileAssets.navHome,
|
|
activeIcon: mobileAssets.navHomeActive,
|
|
},
|
|
{
|
|
label: '记录',
|
|
path: '/app/orders',
|
|
icon: mobileAssets.navOrders,
|
|
activeIcon: mobileAssets.navOrdersActive,
|
|
},
|
|
{
|
|
label: '领取',
|
|
path: '/app/claim',
|
|
icon: mobileAssets.navClaimActive,
|
|
activeIcon: mobileAssets.navClaimActive,
|
|
},
|
|
{
|
|
label: '客服',
|
|
path: '/app/support',
|
|
icon: mobileAssets.navSupport,
|
|
activeIcon: mobileAssets.navSupportActive,
|
|
},
|
|
{
|
|
label: '我的',
|
|
path: '/app/profile',
|
|
icon: mobileAssets.navProfile,
|
|
activeIcon: mobileAssets.navProfileActive,
|
|
},
|
|
];
|
|
const isActive = (path: string) => route.path === path || route.path.startsWith(`${path}/`);
|
|
|
|
function ensureAccess() {
|
|
const publicContent = [
|
|
'/app/content/user_agreement',
|
|
'/app/content/privacy_policy',
|
|
'/app/content/platform_intro',
|
|
];
|
|
const publicPassword = ['/app/password/verify', '/app/password/reset'];
|
|
if (
|
|
!hasSession() &&
|
|
!publicContent.includes(route.path) &&
|
|
!publicPassword.includes(route.path)
|
|
) {
|
|
router.replace({ path: '/app/auth', query: { redirect: route.fullPath } });
|
|
}
|
|
}
|
|
|
|
watch(() => route.path, ensureAccess, { immediate: true });
|
|
</script>
|