main.vue 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <script setup>
  2. import { ref, watch } from 'vue';
  3. import { RouterView, useRoute, useRouter } from 'vue-router';
  4. import { AccountBookOutlined, BookOutlined, LogoutOutlined, TeamOutlined, TrophyOutlined } from '@ant-design/icons-vue';
  5. import { message } from 'ant-design-vue';
  6. import { authState, logout } from '@/stores/auth';
  7. // 获取当前路由和路由实例
  8. const route = useRoute();
  9. const router = useRouter();
  10. const current = ref([route.name]);
  11. // 监听路由变化,更新选中菜单
  12. watch(() => route.name, (newName) => {
  13. current.value = [newName];
  14. });
  15. // 处理菜单点击事件
  16. const handleMenuClick = (e) => {
  17. const key = e.key;
  18. router.push({ name: key });
  19. };
  20. const handleLogout = async () => {
  21. try {
  22. await logout();
  23. router.replace({ name: 'login' });
  24. }
  25. catch (err) {
  26. message.error(err.response?.data?.message ?? err.message);
  27. }
  28. };
  29. </script>
  30. <template>
  31. <header v-if="route.name !== 'login'" class="app-header">
  32. <a-menu class="app-menu" v-model:selectedKeys="current" mode="horizontal" @click="handleMenuClick">
  33. <a-menu-item key="home">
  34. <template #icon>
  35. <account-book-outlined />
  36. </template>
  37. 策略
  38. </a-menu-item>
  39. <a-menu-item key="leagues">
  40. <template #icon>
  41. <team-outlined />
  42. </template>
  43. 联赛
  44. </a-menu-item>
  45. <a-menu-item key="games">
  46. <template #icon>
  47. <trophy-outlined />
  48. </template>
  49. 比赛
  50. </a-menu-item>
  51. <a-menu-item key="locales">
  52. <template #icon>
  53. <book-outlined />
  54. </template>
  55. 翻译
  56. </a-menu-item>
  57. </a-menu>
  58. <div class="header-actions">
  59. <span class="username">{{ authState.user?.username }}</span>
  60. <a-button type="text" @click="handleLogout">
  61. <template #icon>
  62. <logout-outlined />
  63. </template>
  64. 退出
  65. </a-button>
  66. </div>
  67. </header>
  68. <router-view v-slot="{ Component }">
  69. <keep-alive :include="['games', 'leagues', 'locales']">
  70. <component :is="Component" />
  71. </keep-alive>
  72. </router-view>
  73. </template>
  74. <style scoped>
  75. .app-header {
  76. display: flex;
  77. align-items: center;
  78. justify-content: space-between;
  79. border-bottom: 1px solid rgba(5, 5, 5, 0.06);
  80. }
  81. .app-menu {
  82. flex: 1;
  83. min-width: 0;
  84. border-bottom: 0;
  85. }
  86. .header-actions {
  87. display: flex;
  88. align-items: center;
  89. gap: 8px;
  90. padding: 0 16px;
  91. white-space: nowrap;
  92. }
  93. .username {
  94. color: rgba(0, 0, 0, 0.65);
  95. }
  96. </style>