blob: 32d31d4ffbfdf8af13b53f4d2b5a3733aa9b4c22 [file] [log] [blame]
Xing Jinwenebbccad2025-06-07 21:24:44 +08001<template>
2 <div class="navbar">
3 <router-link to="/home" class="navbar-brand">PT Tracker</router-link>
4 <div class="navbar-nav">
5 <router-link to="/home" class="navbar-item">首页</router-link>
6 <router-link to="/torrents" class="navbar-item">种子</router-link>
7 <router-link to="/forum" class="navbar-item">论坛</router-link>
8 <el-dropdown @command="handleUserCommand">
9 <span class="navbar-user">
10 <el-avatar :size="32" :src="userAvatar">
11 {{ username.charAt(0).toUpperCase() }}
12 </el-avatar>
13 <span class="username">{{ username }}</span>
14 <el-icon><ArrowDown /></el-icon>
15 </span>
16 <template #dropdown>
17 <el-dropdown-menu>
18 <el-dropdown-item command="profile">
19 <el-icon><User /></el-icon>
20 个人资料
21 </el-dropdown-item>
22 <el-dropdown-item command="settings">
23 <el-icon><Setting /></el-icon>
24 设置
25 </el-dropdown-item>
26 <el-dropdown-item divided command="logout">
27 <el-icon><SwitchButton /></el-icon>
28 退出登录
29 </el-dropdown-item>
30 </el-dropdown-menu>
31 </template>
32 </el-dropdown>
33 </div>
34 </div>
35</template>
36
37<script>
38import { computed } from 'vue'
39import { useStore } from 'vuex'
40import { useRouter } from 'vue-router'
41import { ElMessageBox } from 'element-plus'
42import {
43 ArrowDown,
44 User,
45 Setting,
46 SwitchButton
47} from '@element-plus/icons-vue'
48
49export default {
50 name: 'Navbar',
51 components: {
52 ArrowDown,
53 User,
54 Setting,
55 SwitchButton
56 },
57 setup() {
58 const store = useStore()
59 const router = useRouter()
60
61 const username = computed(() => store.getters['auth/username'])
62 const userAvatar = computed(() => store.getters['auth/avatar'])
63
64 const handleUserCommand = async (command) => {
65 switch (command) {
66 case 'profile':
67 router.push('/profile')
68 break
69 case 'settings':
70 router.push('/settings')
71 break
72 case 'logout':
73 try {
74 await ElMessageBox.confirm('确定要退出登录吗?', '提示', {
75 confirmButtonText: '确定',
76 cancelButtonText: '取消',
77 type: 'warning'
78 })
79 await store.dispatch('auth/logout')
80 router.push('/login')
81 } catch (error) {
82 if (error !== 'cancel') {
83 console.error('退出登录失败:', error)
84 }
85 }
86 break
87 }
88 }
89
90 return {
91 username,
92 userAvatar,
93 handleUserCommand
94 }
95 }
96}
97</script>
98
99<style lang="scss" scoped>
100.navbar {
101 background: #fff;
102 box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
103 height: 60px;
104 display: flex;
105 align-items: center;
106 justify-content: space-between;
107 padding: 0 24px;
108 position: sticky;
109 top: 0;
110 z-index: 1000;
111}
112
113.navbar-brand {
114 font-size: 20px;
115 font-weight: 700;
116 color: #409eff;
117 text-decoration: none;
118}
119
120.navbar-nav {
121 display: flex;
122 align-items: center;
123 gap: 24px;
124}
125
126.navbar-item {
127 color: #606266;
128 text-decoration: none;
129 font-weight: 500;
130 transition: color 0.3s;
131
132 &:hover {
133 color: #409eff;
134 }
135}
136
137.navbar-user {
138 display: flex;
139 align-items: center;
140 gap: 8px;
141 cursor: pointer;
142 padding: 8px;
143 border-radius: 6px;
144 transition: background-color 0.3s;
145
146 &:hover {
147 background-color: #f5f7fa;
148 }
149
150 .username {
151 font-weight: 500;
152 color: #303133;
153 }
154}
155
156@media (max-width: 768px) {
157 .navbar {
158 padding: 0 16px;
159
160 .navbar-nav {
161 gap: 16px;
162 }
163
164 .navbar-user .username {
165 display: none;
166 }
167 }
168}
169</style>