<template> | |
<div class="navbar"> | |
<router-link to="/home" class="navbar-brand">PT Tracker</router-link> | |
<div class="navbar-nav"> | |
<router-link to="/home" class="navbar-item">首页</router-link> | |
<router-link to="/torrents" class="navbar-item">种子</router-link> | |
<router-link to="/forum" class="navbar-item">论坛</router-link> | |
<el-dropdown @command="handleUserCommand"> | |
<span class="navbar-user"> | |
<el-avatar :size="32" :src="userAvatar"> | |
{{ username.charAt(0).toUpperCase() }} | |
</el-avatar> | |
<span class="username">{{ username }}</span> | |
<el-icon><ArrowDown /></el-icon> | |
</span> | |
<template #dropdown> | |
<el-dropdown-menu> | |
<el-dropdown-item command="profile"> | |
<el-icon><User /></el-icon> | |
个人资料 | |
</el-dropdown-item> | |
<el-dropdown-item command="settings"> | |
<el-icon><Setting /></el-icon> | |
设置 | |
</el-dropdown-item> | |
<el-dropdown-item divided command="logout"> | |
<el-icon><SwitchButton /></el-icon> | |
退出登录 | |
</el-dropdown-item> | |
</el-dropdown-menu> | |
</template> | |
</el-dropdown> | |
</div> | |
</div> | |
</template> | |
<script> | |
import { computed } from 'vue' | |
import { useStore } from 'vuex' | |
import { useRouter } from 'vue-router' | |
import { ElMessageBox } from 'element-plus' | |
import { | |
ArrowDown, | |
User, | |
Setting, | |
SwitchButton | |
} from '@element-plus/icons-vue' | |
export default { | |
name: 'Navbar', | |
components: { | |
ArrowDown, | |
User, | |
Setting, | |
SwitchButton | |
}, | |
setup() { | |
const store = useStore() | |
const router = useRouter() | |
const username = computed(() => store.getters['auth/username']) | |
const userAvatar = computed(() => store.getters['auth/avatar']) | |
const handleUserCommand = async (command) => { | |
switch (command) { | |
case 'profile': | |
router.push('/profile') | |
break | |
case 'settings': | |
router.push('/settings') | |
break | |
case 'logout': | |
try { | |
await ElMessageBox.confirm('确定要退出登录吗?', '提示', { | |
confirmButtonText: '确定', | |
cancelButtonText: '取消', | |
type: 'warning' | |
}) | |
await store.dispatch('auth/logout') | |
router.push('/login') | |
} catch (error) { | |
if (error !== 'cancel') { | |
console.error('退出登录失败:', error) | |
} | |
} | |
break | |
} | |
} | |
return { | |
username, | |
userAvatar, | |
handleUserCommand | |
} | |
} | |
} | |
</script> | |
<style lang="scss" scoped> | |
.navbar { | |
background: #fff; | |
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1); | |
height: 60px; | |
display: flex; | |
align-items: center; | |
justify-content: space-between; | |
padding: 0 24px; | |
position: sticky; | |
top: 0; | |
z-index: 1000; | |
} | |
.navbar-brand { | |
font-size: 20px; | |
font-weight: 700; | |
color: #409eff; | |
text-decoration: none; | |
} | |
.navbar-nav { | |
display: flex; | |
align-items: center; | |
gap: 24px; | |
} | |
.navbar-item { | |
color: #606266; | |
text-decoration: none; | |
font-weight: 500; | |
transition: color 0.3s; | |
&:hover { | |
color: #409eff; | |
} | |
} | |
.navbar-user { | |
display: flex; | |
align-items: center; | |
gap: 8px; | |
cursor: pointer; | |
padding: 8px; | |
border-radius: 6px; | |
transition: background-color 0.3s; | |
&:hover { | |
background-color: #f5f7fa; | |
} | |
.username { | |
font-weight: 500; | |
color: #303133; | |
} | |
} | |
@media (max-width: 768px) { | |
.navbar { | |
padding: 0 16px; | |
.navbar-nav { | |
gap: 16px; | |
} | |
.navbar-user .username { | |
display: none; | |
} | |
} | |
} | |
</style> |