初始化
This commit is contained in:
@@ -70,6 +70,18 @@
|
||||
{{ tech }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<h3 class="text-xl font-bold text-white mb-6 flex items-center gap-2">
|
||||
<i data-lucide="briefcase" class="w-5 h-5 text-art-accent"></i> 经历
|
||||
</h3>
|
||||
<div class="space-y-6 relative border-l border-white/10 ml-2 pl-6">
|
||||
<div v-for="(exp, index) in profile.experiences" :key="index" class="relative">
|
||||
<div class="absolute -left-[29px] top-1.5 w-3 h-3 rounded-full" :class="index === 0 ? 'bg-art-accent' : 'bg-white/20'"></div>
|
||||
<div class="text-sm font-mono mb-1" :class="index === 0 ? 'text-art-accent' : 'text-art-muted'">{{ exp.year }}</div>
|
||||
<div class="text-white font-bold">{{ exp.role }}</div>
|
||||
<div class="text-xs text-art-muted">{{ exp.company }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -78,10 +90,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, onBeforeMount } from 'vue'
|
||||
import { ref, onMounted, onUpdated, nextTick } from 'vue'
|
||||
import { useScrollAnimation } from '../composables/useScrollAnimation'
|
||||
import { fetchAboutProfile } from '../services/api'
|
||||
|
||||
// 定义类型
|
||||
interface Experience {
|
||||
year: string
|
||||
role: string
|
||||
company: string
|
||||
}
|
||||
|
||||
interface Profile {
|
||||
id: string
|
||||
name: string
|
||||
@@ -93,19 +112,21 @@ interface Profile {
|
||||
wechat: string
|
||||
}
|
||||
techStack: string[]
|
||||
experiences: Experience[]
|
||||
}
|
||||
|
||||
const profile = ref<Profile>({
|
||||
id: '',
|
||||
name: '年糕崽崽',
|
||||
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=NianGao&backgroundColor=b6e3f4',
|
||||
location: '中国 · 浙江杭州',
|
||||
bio: '嗨!我是年糕崽崽,一名热衷于探索数字边界的前端架构师。我的职业生涯始于对像素级完美的执念。目前,我专注于高性能 B 端应用的体验升级。',
|
||||
name: '',
|
||||
avatar: '',
|
||||
location: '',
|
||||
bio: '',
|
||||
contact: {
|
||||
email: 'hello@niangao.dev',
|
||||
wechat: 'Niangao_Dev'
|
||||
email: '',
|
||||
wechat: ''
|
||||
},
|
||||
techStack: ['Vue 3', 'React', 'TypeScript', 'Three.js', 'Golang', 'Tailwind CSS', 'Vite', 'Gin']
|
||||
techStack: [],
|
||||
experiences: []
|
||||
})
|
||||
|
||||
const loading = ref(false)
|
||||
@@ -113,45 +134,48 @@ const error = ref('')
|
||||
|
||||
const { initObserver } = useScrollAnimation()
|
||||
|
||||
// 模拟API调用,实际项目中应替换为真实API
|
||||
const refreshIcons = () => {
|
||||
if ((window as any).lucide) {
|
||||
(window as any).lucide.createIcons()
|
||||
}
|
||||
}
|
||||
|
||||
const fetchProfileData = async () => {
|
||||
loading.value = true
|
||||
error.value = ''
|
||||
try {
|
||||
// 实际项目中应调用真实API
|
||||
// const response = await fetch(`${API_BASE}/profile`)
|
||||
// const data = await response.json()
|
||||
// profile.value = data
|
||||
|
||||
// 使用模拟数据作为备选
|
||||
const data = await fetchAboutProfile()
|
||||
profile.value = {
|
||||
id: '1',
|
||||
name: '年糕崽崽',
|
||||
avatar: 'https://api.dicebear.com/7.x/avataaars/svg?seed=NianGao&backgroundColor=b6e3f4',
|
||||
location: '中国 · 浙江杭州',
|
||||
bio: '嗨!我是年糕崽崽,一名热衷于探索数字边界的前端架构师。我的职业生涯始于对像素级完美的执念。目前,我专注于高性能 B 端应用的体验升级。',
|
||||
id: String(data.id),
|
||||
name: data.name,
|
||||
avatar: data.avatar,
|
||||
location: data.location,
|
||||
bio: data.bio,
|
||||
contact: {
|
||||
email: 'hello@niangao.dev',
|
||||
wechat: 'Niangao_Dev'
|
||||
email: data.email,
|
||||
wechat: data.wechat
|
||||
},
|
||||
techStack: ['Vue 3', 'React', 'TypeScript', 'Three.js', 'Golang', 'Tailwind CSS', 'Vite', 'Gin']
|
||||
techStack: data.techStack,
|
||||
experiences: data.experiences || []
|
||||
}
|
||||
// 初始化动画
|
||||
initObserver()
|
||||
} catch (err) {
|
||||
console.error('Error fetching profile data:', err)
|
||||
error.value = '获取个人资料失败,请稍后重试'
|
||||
// 保持原有静态数据
|
||||
} finally {
|
||||
loading.value = false
|
||||
nextTick(() => {
|
||||
initObserver()
|
||||
refreshIcons()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchProfileData()
|
||||
// 初始化Lucide图标
|
||||
if (window.lucide) {
|
||||
window.lucide.createIcons()
|
||||
}
|
||||
refreshIcons()
|
||||
})
|
||||
|
||||
onUpdated(() => {
|
||||
refreshIcons()
|
||||
})
|
||||
</script>
|
||||
@@ -854,3 +854,40 @@ export const deleteTag = async (id: number): Promise<void> => {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
// 关于页面相关类型
|
||||
export interface Experience {
|
||||
year: string
|
||||
role: string
|
||||
company: string
|
||||
}
|
||||
|
||||
export interface AboutProfile {
|
||||
id: number
|
||||
name: string
|
||||
avatar: string
|
||||
location: string
|
||||
bio: string
|
||||
email: string
|
||||
wechat: string
|
||||
techStack: string[]
|
||||
experiences: Experience[]
|
||||
isPrimary: boolean
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
// 关于页面API
|
||||
export const fetchAboutProfile = async (): Promise<AboutProfile> => {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE}/about`)
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json()
|
||||
throw new Error(errorData.error || '获取个人资料失败')
|
||||
}
|
||||
return await response.json()
|
||||
} catch (error) {
|
||||
console.error('Fetch about profile error:', error)
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user