UserLayout.vue 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. <template>
  2. <div class="user-layout">
  3. <el-container>
  4. <el-header class="header">
  5. <div class="header-left" @click="router.push('/')">
  6. <img :src="metaStore.logo" alt="logo" class="logo">
  7. <h2 class="title">{{metaStore.title}}</h2>
  8. </div>
  9. <el-menu
  10. :default-active="activeIndex"
  11. mode="horizontal"
  12. router
  13. @select="handleSelect"
  14. class="nav-menu"
  15. >
  16. <el-menu-item :index="menu.path" v-for="menu in menus" :key="menu.path">
  17. <el-icon><component :is="menu.meta?.icon"/></el-icon>
  18. <template #title>{{ menu.meta?.title }}</template>
  19. </el-menu-item>
  20. <el-menu-item v-if="isStaff" index="/admin">
  21. <el-icon><Tools/></el-icon>
  22. <template #title>后台管理</template>
  23. </el-menu-item>
  24. </el-menu>
  25. <div class="header-right">
  26. <template v-if="login">
  27. <el-dropdown placement="bottom">
  28. <el-button class="user-btn" text>
  29. <el-icon class="user-avatar"><UserFilled /></el-icon>
  30. <span class="username">{{ loginUserStore.loginUser?.user?.name }}</span>
  31. </el-button>
  32. <template #dropdown>
  33. <el-dropdown-menu>
  34. <el-dropdown-item>个人信息</el-dropdown-item>
  35. <el-dropdown-item divided @click="logoutHandler">退出登录</el-dropdown-item>
  36. </el-dropdown-menu>
  37. </template>
  38. </el-dropdown>
  39. </template>
  40. <template v-else>
  41. <el-button type="primary" size="small" @click="loginHandler">登录</el-button>
  42. <el-button size="small" @click="router.push('/login')">注册</el-button>
  43. </template>
  44. </div>
  45. </el-header>
  46. <el-main>
  47. <router-view/>
  48. </el-main>
  49. <el-footer>Footer</el-footer>
  50. </el-container>
  51. </div>
  52. </template>
  53. <script setup lang="ts">
  54. import {computed, ref} from 'vue'
  55. import {useLoginUserStore, useMetaStore} from "../store";
  56. import router, {userRoutes} from "../router";
  57. import {
  58. Tools,
  59. UserFilled
  60. } from '@element-plus/icons-vue'
  61. const metaStore = useMetaStore()
  62. const loginUserStore = useLoginUserStore()
  63. const login = computed(() => loginUserStore.loginUser.isLogin)
  64. const isStaff = computed(() => {
  65. const role = loginUserStore.loginUser.user?.role
  66. return role === 'admin' || role === 'coach'
  67. })
  68. const loginHandler = () => {
  69. router.push('/login')
  70. }
  71. let activeIndex = ref('/')
  72. const menus = computed(()=>{
  73. return userRoutes[0].children?.filter((child) => !String(child.path).includes(':'));
  74. })
  75. const handleSelect = () => {
  76. //todo: 处理菜单选择
  77. }
  78. const logoutHandler = () => {
  79. loginUserStore.logoutUser()
  80. router.push('/')
  81. }
  82. </script>
  83. <style scoped>
  84. .user-layout {
  85. display: flex;
  86. flex-direction: column;
  87. min-height: 100vh;
  88. }
  89. el-main{
  90. flex: 1;
  91. }
  92. .header {
  93. display: flex;
  94. align-items: center;
  95. justify-content: space-between;
  96. padding: 0 20px;
  97. }
  98. .header-left {
  99. display: flex;
  100. align-items: center;
  101. gap: 10px;
  102. }
  103. .logo {
  104. width: 40px;
  105. height: 40px;
  106. }
  107. .title {
  108. margin: 0;
  109. font-size: 20px;
  110. }
  111. .nav-menu {
  112. flex: 1;
  113. display: flex;
  114. justify-content: center;
  115. border-bottom: none;
  116. }
  117. .header-right {
  118. display: flex;
  119. align-items: center;
  120. gap: 10px;
  121. }
  122. .username {
  123. font-size: 14px;
  124. color: #606266;
  125. }
  126. .user-btn {
  127. display: flex;
  128. align-items: center;
  129. gap: 6px;
  130. cursor: pointer;
  131. transition: color 0.2s;
  132. }
  133. .user-btn:hover {
  134. color: #db2777;
  135. }
  136. .user-avatar {
  137. font-size: 20px;
  138. color: #be185d;
  139. }
  140. </style>