2026-05-01 12:24:23 +09:00

199 lines
3.9 KiB
Vue

<template>
<header class="app-header">
<div class="header-user">
<img
src="https://placehold.co/52x52/e9eef9/8f9db7?text=%E5%A4%B4"
alt="学生头像"
class="user-avatar"
/>
<div class="user-info">
<p class="user-name">HI, 张小小</p>
<span class="user-level">Lv1</span>
</div>
</div>
<div class="header-actions">
<button class="grade-btn">
七年级
<span class="grade-arrow"></span>
</button>
<div class="divider" />
<div class="action-list">
<button
v-for="item in actions"
:key="item.label"
class="action-item"
type="button"
@click="handleActionClick(item)"
>
<span class="action-icon">
<img
v-if="item.iconSrc"
:src="item.iconSrc"
:alt="item.label"
class="action-icon-img"
/>
<template v-else>{{ item.icon }}</template>
</span>
<span class="action-label">{{ item.label }}</span>
<span v-if="item.badge > 0" class="action-badge">
{{ item.badge }}
</span>
</button>
</div>
</div>
</header>
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router'
import xinxiangIcon from '@/assets/header/xinxiang.png'
import huodongIcon from '@/assets/header/huodong.png'
import setupIcon from '@/assets/header/setup.png'
const actions = [
{ label: '排行榜', icon: '□', iconSrc: xinxiangIcon, badge: 1, routeName: 'ranking-list' },
{ label: '学员管理', icon: '□', iconSrc: xinxiangIcon, badge: 1, routeName: 'student-management' },
{ label: '作业', icon: '□', iconSrc: xinxiangIcon, badge: 1 },
{ label: '信箱', icon: '✉', iconSrc: xinxiangIcon, badge: 1 },
{ label: '活动', icon: '▣', iconSrc: huodongIcon, badge: 1 },
{ label: '设置', icon: '⚙', iconSrc: setupIcon, badge: 0 },
]
const router = useRouter()
function handleActionClick(item: (typeof actions)[number]) {
if (!item.routeName) return
router.push({ name: item.routeName })
}
</script>
<style scoped lang="scss">
.app-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
border-radius: 12px;
padding: 32px 64px;
}
.header-user {
display: flex;
align-items: center;
gap: 12px;
height: 88px;
}
.user-avatar {
height: 88px;
width: 88px;
border-radius: 50%;
border: 1px solid #d0daec;
object-fit: cover;
}
.user-info {
display: flex;
align-items: center;
gap: 8px;
}
.user-name {
font-size: 34px;
font-weight: 600;
color: #121212;
}
.user-level {
border-radius: 6px;
background: #3d78f2;
padding: 2px 6px;
font-size: 12px;
color: #fff;
}
.header-actions {
display: flex;
align-items: center;
gap: 32px;
}
.grade-btn {
font-size: 28px;
color: #3f4f6e;
background: transparent;
border: none;
cursor: pointer;
}
.grade-arrow {
margin-left: 4px;
font-size: 12px;
}
.divider {
height: 24px;
width: 2px;
background: #666;
}
.action-list {
display: flex;
align-items: center;
gap: 32px;
}
.action-item {
position: relative;
display: flex;
align-items: center;
border: none;
background: transparent;
color: #1f2937;
cursor: pointer;
font: inherit;
padding: 0;
// margin-left: 16px;
}
.action-icon {
display: inline-flex;
height: 48px;
width: 48px;
align-items: center;
justify-content: center;
border-radius: 4px;
font-size: 14px;
// margin-left: 16px;
}
.action-icon-img {
height: 48px;
width: 48px;
object-fit: contain;
}
.action-label {
margin-left: 16px;
font-size: 28px;
}
.action-badge {
position: absolute;
right: -4px;
top: -4px;
display: inline-flex;
height: 16px;
min-width: 16px;
align-items: center;
justify-content: center;
border-radius: 9999px;
background: #ef4444;
padding: 0 4px;
font-size: 10px;
font-weight: 500;
color: #fff;
}
</style>