feat(layout): 实现用户头像动态显示和个人信息本地存储

- 在布局头部组件中添加用户头像条件渲染逻辑
- 从localStorage获取用户信息并解析用户名和头像数据
- 为布局侧边栏组件添加相同的头像显示功能
- 在个人资料页面实现头像的动态切换显示
- 添加错误处理确保用户信息读取失败时显示默认值
- 重构用户初始字母计算逻辑以适应响应式数据结构
This commit is contained in:
Yuhang Wu 2026-07-30 15:09:04 +08:00
parent 0ae78b2d6f
commit d0ecbaf3ab
3 changed files with 36 additions and 7 deletions

View File

@ -35,7 +35,8 @@
</n-tooltip>
<n-dropdown trigger="click" :options="userDropdownOptions" @select="onUserAction">
<div class="header-user">
<n-avatar round size="small" :style="{ backgroundColor: '#0891B2' }">
<n-avatar v-if="userAvatar" round size="small" :src="userAvatar" />
<n-avatar v-else round size="small" :style="{ backgroundColor: '#0891B2' }">
{{ userInitial }}
</n-avatar>
<span class="header-username">{{ username }}</span>
@ -73,8 +74,21 @@ const message = useMessage()
const layoutStore = useLayoutStore()
const themeStore = useThemeStore()
const username = 'SparksFly'
const userInitial = computed(() => username.charAt(0).toUpperCase())
const username = computed(() => {
try {
const stored = localStorage.getItem('userInfo')
if (stored) return JSON.parse(stored).user_name || 'Guest'
} catch {}
return 'Guest'
})
const userAvatar = computed(() => {
try {
const stored = localStorage.getItem('userInfo')
if (stored) return JSON.parse(stored).avatar || ''
} catch {}
return ''
})
const userInitial = computed(() => username.value.charAt(0).toUpperCase())
const currentRouteTitle = computed(() => (route.meta?.title as string) || '')

View File

@ -41,7 +41,8 @@
<!-- 用户区 -->
<transition name="fade-text">
<div v-if="!layoutStore.siderCollapsed" class="sider-user">
<n-avatar round size="small" :style="{ backgroundColor: '#0891B2' }">
<n-avatar v-if="userAvatar" round size="small" :src="userAvatar" />
<n-avatar v-else round size="small" :style="{ backgroundColor: '#0891B2' }">
{{ userInitial }}
</n-avatar>
<div class="user-meta">
@ -86,8 +87,21 @@ const message = useMessage()
const layoutStore = useLayoutStore()
//
const username = 'SparksFly'
const userInitial = computed(() => username.charAt(0).toUpperCase())
const username = computed(() => {
try {
const stored = localStorage.getItem('userInfo')
if (stored) return JSON.parse(stored).user_name || 'Guest'
} catch {}
return 'Guest'
})
const userAvatar = computed(() => {
try {
const stored = localStorage.getItem('userInfo')
if (stored) return JSON.parse(stored).avatar || ''
} catch {}
return ''
})
const userInitial = computed(() => username.value.charAt(0).toUpperCase())
// Icon helper
function renderIcon(icon: Component) {

View File

@ -9,7 +9,8 @@
<!-- 左侧信息卡 -->
<div class="profile-card card">
<div class="avatar-wrap">
<n-avatar round :size="80" :style="{ backgroundColor: '#0891B2', fontSize: '32px' }">
<n-avatar v-if="form.avatar" round :size="80" :src="form.avatar" />
<n-avatar v-else round :size="80" :style="{ backgroundColor: '#0891B2', fontSize: '32px' }">
{{ userInitial }}
</n-avatar>
<div class="avatar-info">