| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- <script setup lang="ts">
- import { ref, onMounted, onBeforeUnmount, computed } from "vue";
- import Header from "@/components/layout/Header.vue";
- import Footer from "@/components/layout/Footer.vue";
- import Home from "@/views/Home.vue";
- import Purchased from "@/views/Purchased.vue";
- import Account from "@/views/Account.vue";
- import Favorite from "@/views/Favorite.vue";
- import LoginDialog from "@/components/LoginDialog.vue";
- import { useUserStore } from "@/store/user";
- type TabKey = "home" | "purchased" | "account" | "favorite";
- const active = ref<TabKey>("home");
- const showScrollTop = ref(false);
- const showLoginDialog = ref(false);
- const userStore = useUserStore();
- const isLoggedIn = computed(() => !!userStore.token);
- function handleScroll() {
- showScrollTop.value = window.scrollY > 320;
- }
- function scrollToTop() {
- window.scrollTo({ top: 0, behavior: "smooth" });
- }
- function switchTab(key: TabKey) {
- // 如果用户点击"已购买"但未登录,则显示登录弹窗
- if (key === "purchased" && !isLoggedIn.value) {
- showLoginDialog.value = true;
- return;
- }
- active.value = key;
- }
- function handleLoginSuccess() {
- // 登录成功后的处理
- if (active.value === "account") {
- // 如果在账号页面登录成功,刷新用户信息
- userStore.sync();
- }
- }
- onMounted(() => {
- window.addEventListener("scroll", handleScroll, { passive: true });
- // 如果有token,同步用户信息
- if (userStore.token) {
- userStore.sync().catch(() => {
- // 如果同步失败,可能是token过期,清除登录状态
- userStore.logout();
- });
- }
- });
- onBeforeUnmount(() => {
- window.removeEventListener("scroll", handleScroll);
- });
- </script>
- <template>
- <div
- class="min-h-screen bg-surface text-slate-100 selection:bg-brand/20 selection:text-brand"
- >
- <Header @show-login="showLoginDialog = true" @switch-tab="switchTab" />
- <main class="max-w-screen-sm mx-auto w-full px-4 pb-28 pt-3">
- <Home v-if="active === 'home'" />
- <Purchased v-else-if="active === 'purchased' && isLoggedIn" />
- <Account
- v-else-if="active === 'account'"
- @show-login="showLoginDialog = true"
- />
- <Favorite v-else-if="active === 'favorite'" />
- </main>
- <button
- v-show="showScrollTop"
- @click="scrollToTop"
- class="fixed right-4 bottom-28 z-40 h-11 w-11 rounded-full bg-brand text-slate-900 shadow-lg grid place-items-center active:scale-95 transition"
- aria-label="回到顶部"
- >
- <svg
- viewBox="0 0 24 24"
- width="22"
- height="22"
- fill="none"
- stroke="currentColor"
- stroke-width="2"
- class="text-slate-900"
- >
- <path d="m5 15 7-7 7 7" />
- </svg>
- </button>
- <Footer :active="active" @switch-tab="switchTab" />
- <LoginDialog
- v-model="showLoginDialog"
- @login-success="handleLoginSuccess"
- />
- </div>
- </template>
|