个人作品集网站开发实战
作为一名开发者,拥有一个专业的个人作品集网站是展示技能和吸引机会的重要工具。本文将详细记录我开发个人作品集网站的完整过程。
项目背景与目标
为什么需要作品集网站?
在当今竞争激烈的技术领域,一个优秀的作品集网站能够:
- 展示技术能力和项目经验
- 建立个人品牌和在线形象
- 吸引潜在雇主或客户
- 记录和分享技术学习历程
项目目标
-
功能目标
- 展示个人信息和技能
- 项目作品展示
- 技术博客系统
- 联系方式和社交媒体链接
-
技术目标
- 使用现代Web技术栈
- 优秀的性能表现
- 完整的SEO优化
- 响应式设计
技术选型决策
前端框架:Next.js 14
选择Next.js的原因:
- 全栈能力: 支持SSR、SSG、API routes
- 性能优异: 自动代码分割、图片优化
- SEO友好: 服务端渲染支持
- 开发体验: 优秀的开发工具和热重载
样式方���:Tailwind CSS
CSS
/* 传统CSS写法 */
.button {
background-color: #3b82f6;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.375rem;
border: none;
cursor: pointer;
}
.button:hover {
background-color: #2563eb;
}
React JSX
/* Tailwind CSS写法 */
<button className="bg-blue-500 hover:bg-blue-600 text-white px-4 py-2 rounded">
Click me
</button>
Tailwind的优势:
- 快速开发
- 一致的设计系统
- 优秀的响应式支持
- 自动清除未使用的样式
内容管理:Markdown + Gray Matter
选择基于文件的内容管理而非CMS:
- 版本控制友好
- 开发者友好的编写体验
- 无额外服务依赖
- 完全可控的数据结构
设计理念与实现
视觉设计
色彩方案
选择了温暖的粉色作为主色调:
CSS
:root {
--color-primary: #ec4899;
--color-primary-light: #f9a8d4;
--color-primary-dark: #be185d;
}
布局设计
采用简洁的卡片式布局:
- 清晰的信息层级
- 充足的留白空间
- 一致的圆角和阴影
- 平滑的过渡动画
核心功能实现
1. 响应式导航
React TSX
function Navigation() {
const [isOpen, setIsOpen] = useState(false)
return (
<nav className="sticky top-0 bg-white/80 backdrop-blur-md">
<div className="max-w-6xl mx-auto px-8">
<div className="flex justify-between items-center py-4">
<Link href="/" className="text-2xl font-bold">
Q1Hang
</Link>
{/* Desktop Menu */}
<div className="hidden md:flex space-x-8">
<NavLink href="/">Home</NavLink>
<NavLink href="/blog">Blog</NavLink>
</div>
{/* Mobile Menu Toggle */}
<button
onClick={() => setIsOpen(!isOpen)}
className="md:hidden"
>
{isOpen ? <X /> : <Menu />}
</button>
</div>
</div>
</nav>
)
}
2. 项目展示卡片
React TSX
function ProjectCard({ project }: { project: Project }) {
return (
<div className="bg-pink-50 border border-pink-200 rounded-2xl p-6 h-full flex flex-col hover:border-pink-300 hover:shadow-lg transition-all duration-200">
<h3 className="text-xl font-bold mb-3 text-black">
{project.title}
</h3>
<p className="text-gray-600 flex-grow min-h-[80px] mb-4">
{project.description}
</p>
<div className="flex flex-wrap gap-2 mb-4">
{project.tech.map((tech) => (
<span key={tech} className="bg-white px-3 py-1 rounded-full text-sm">
{tech}
</span>
))}
</div>
<a
href={project.github}
className="bg-pink-500 hover:bg-pink-600 text-white px-4 py-2 rounded-lg font-medium transition-colors mt-auto"
>
View Project
</a>
</div>
)
}
3. 博客系统
文章数据结构:
TypeScript
interface Post {
slug: string
title: string
date: string
category: 'tech' | 'life' | 'projects'
description: string
tags: string[]
content: string
readingTime: number
featured?: boolean
}
文章解析逻辑:
TypeScript
export function getAllPosts(): Post[] {
const categories = ['tech', 'life', 'projects']
const allPosts: Post[] = []
categories.forEach(category => {
const categoryPath = path.join(postsDirectory, category)
if (!fs.existsSync(categoryPath)) return
const files = fs.readdirSync(categoryPath)
files.forEach(fileName => {
if (!fileName.endsWith('.md')) return
const slug = fileName.replace(/\.md$/, '')
const fullPath = path.join(categoryPath, fileName)
const fileContents = fs.readFileSync(fullPath, 'utf8')
const { data, content } = matter(fileContents)
allPosts.push({
slug,
title: data.title,
date: data.date,
category: category as Post['category'],
description: data.description,
tags: data.tags || [],
content,
readingTime: calculateReadingTime(content),
featured: data.featured || false
})
})
})
return allPosts.sort((a, b) =>
new Date(b.date).getTime() - new Date(a.date).getTime()
)
}
性能优化策略
1. 图片优化
使用Next.js的Image组件:
React TSX
import Image from 'next/image'
<Image
src="/avatar.jpg"
alt="Profile"
width={256}
height={256}
className="rounded-full"
priority
/>
优化效果:
- 自动WebP格式转换
- 响应式图片生成
- 懒加载和预加载
- 自动尺寸优化
2. 代码分割
Next.js自动实现的优化:
- 页面级代码分割
- 动态导入支持
- 共享代码提取
- 预取关键资源
3. 静态生成
博客文章使用SSG:
TypeScript
export async function generateStaticParams() {
const posts = getAllPosts()
return posts.map((post) => ({
slug: post.slug,
}))
}
export async function generateMetadata({ params }: Props) {
const post = getPostBySlug(params.slug)
return {
title: `${post.title} - Q1Hang`,
description: post.description,
openGraph: {
title: post.title,
description: post.description,
type: 'article',
}
}
}
SEO优化实践
1. 元数据管理
TypeScript
// 全局元数据
export const metadata: Metadata = {
title: 'Q1Hang - Full Stack Developer',
description: 'Passionate developer interested in AI and modern web technologies',
keywords: ['Next.js', 'React', 'TypeScript', 'Full Stack'],
authors: [{ name: 'Q1Hang' }],
openGraph: {
type: 'website',
locale: 'zh_CN',
url: 'https://your-domain.com',
siteName: 'Q1Hang Portfolio',
}
}
2. 结构化数据
为博客文章添加JSON-LD:
TypeScript
function generateArticleSchema(post: Post) {
return {
"@context": "https://schema.org",
"@type": "Article",
"headline": post.title,
"description": post.description,
"author": {
"@type": "Person",
"name": "Q1Hang"
},
"datePublished": post.date,
"keywords": post.tags.join(', ')
}
}
3. 网站地图生成
TypeScript
// app/sitemap.ts
export default function sitemap(): MetadataRoute.Sitemap {
const posts = getAllPosts()
const postUrls = posts.map((post) => ({
url: `https://your-domain.com/blog/${post.slug}`,
lastModified: new Date(post.date),
changeFrequency: 'monthly' as const,
priority: 0.8,
}))
return [
{
url: 'https://your-domain.com',
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 1,
},
{
url: 'https://your-domain.com/blog',
lastModified: new Date(),
changeFrequency: 'weekly',
priority: 0.9,
},
...postUrls,
]
}
部署与运维
Vercel部署流程
-
连接GitHub仓库
- 自动检测Next.js项目
- 配置构建和部署设置
-
环境变量配置
BashNEXT_PUBLIC_SITE_URL=https://your-domain.com
-
自定义域名
- DNS配置
- SSL证书自动管理
性能监控
使用Vercel Analytics:
- 页面性能指标
- 用户行为分析
- Core Web Vitals监控
项目成果与反思
技术成果
- ✅ 完全响应式设计
- ✅ 优秀的性能表现 (Lighthouse 95+)
- ✅ 完整的SEO优化
- ✅ 现代化的开发体验
性能数据
- 首屏加载时间: < 1.5s
- 累积布局偏移: < 0.1
- 最大内容绘制: < 2.5s
- 首次输入延迟: < 100ms
经验总结
技术层面
- 框架选择很重要: Next.js的全栈能力大大简化了开发
- 性能优化要从设计开始: 而不是事后补救
- 类型安全的价值: TypeScript帮助避免了很多潜在问题
设计层面
- 简洁胜过复杂: 用户更关注内容而非炫技
- 一致性原则: 统一的设计语言提升用户体验
- 移动优先: 大部分用户通过移动设备访问
后续优化计划
功能扩展
- 博客文章搜索功能
- 标签页面和标签云
- 文章阅读进度指示器
- 深色模式支持
技术优化
- 更细粒度的代码分割
- Service Worker缓存策略
- 图片懒加载优化
- 微交互动画增强
结语
这个作品集网站项目不仅是技术能力的展示,更是一个持续学习和优化的过程。通过实际项目的驱动,我深入掌握了现代Web开发的最佳实践,也更好地理解了用户体验设计的重要性。
对于想要建设自己作品集网站的开发者,我的建议是:
- 先规划,后开发
- 重视用户体验
- 持续优化和迭代
- 记录和分享经验
技术在变化,但优质内容和良好体验的追求是永恒的。希望这个项目能够为其他开发者提供一些参考和启发。