第一个项目 #
一、项目概述 #
我们将创建一个简单的个人主页项目,包含以下功能:
- 首页展示个人信息
- 关于页面
- 项目展示页面
- 响应式导航栏
项目预览 #
text
┌─────────────────────────────────────────────────────┐
│ 我的主页 │
├─────────────────────────────────────────────────────┤
│ [首页] [关于] [项目] 个人主页 │
├─────────────────────────────────────────────────────┤
│ │
│ 你好,我是开发者 │
│ 欢迎来到我的个人主页 │
│ │
│ [了解更多] [查看项目] │
│ │
└─────────────────────────────────────────────────────┘
二、创建项目 #
2.1 初始化项目 #
bash
# 创建项目
npm create astro@latest my-portfolio
# 进入项目目录
cd my-portfolio
# 启动开发服务器
npm run dev
2.2 项目结构 #
创建以下目录结构:
text
my-portfolio/
├── public/
│ └── favicon.svg
├── src/
│ ├── components/
│ │ ├── Header.astro
│ │ ├── Footer.astro
│ │ └── Hero.astro
│ ├── layouts/
│ │ └── Layout.astro
│ ├── pages/
│ │ ├── index.astro
│ │ ├── about.astro
│ │ └── projects.astro
│ └── styles/
│ └── global.css
├── astro.config.mjs
└── package.json
三、创建布局组件 #
3.1 基础布局 #
创建 src/layouts/Layout.astro:
astro
---
interface Props {
title: string;
}
const { title } = Astro.props;
---
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="我的个人主页" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<title>{title}</title>
</head>
<body>
<slot />
</body>
</html>
<style is:global>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: system-ui, -apple-system, sans-serif;
line-height: 1.6;
color: #333;
}
a {
color: inherit;
text-decoration: none;
}
</style>
四、创建通用组件 #
4.1 导航头部 #
创建 src/components/Header.astro:
astro
---
const navItems = [
{ label: '首页', href: '/' },
{ label: '关于', href: '/about' },
{ label: '项目', href: '/projects' },
];
---
<header class="header">
<nav class="nav">
<a href="/" class="logo">我的主页</a>
<ul class="nav-list">
{navItems.map((item) => (
<li>
<a href={item.href} class="nav-link">
{item.label}
</a>
</li>
))}
</ul>
</nav>
</header>
<style>
.header {
background: #fff;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
position: sticky;
top: 0;
z-index: 100;
}
.nav {
max-width: 1200px;
margin: 0 auto;
padding: 1rem 2rem;
display: flex;
justify-content: space-between;
align-items: center;
}
.logo {
font-size: 1.5rem;
font-weight: bold;
color: #2563eb;
}
.nav-list {
display: flex;
list-style: none;
gap: 2rem;
}
.nav-link {
padding: 0.5rem 1rem;
border-radius: 4px;
transition: background-color 0.2s;
}
.nav-link:hover {
background-color: #f3f4f6;
}
</style>
4.2 页脚组件 #
创建 src/components/Footer.astro:
astro
---
const year = new Date().getFullYear();
---
<footer class="footer">
<div class="footer-content">
<p>© {year} 我的主页. 保留所有权利.</p>
<div class="social-links">
<a href="https://github.com" target="_blank" rel="noopener">GitHub</a>
<a href="https://twitter.com" target="_blank" rel="noopener">Twitter</a>
</div>
</div>
</footer>
<style>
.footer {
background: #f3f4f6;
padding: 2rem;
margin-top: auto;
}
.footer-content {
max-width: 1200px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: center;
}
.social-links {
display: flex;
gap: 1rem;
}
.social-links a {
color: #6b7280;
transition: color 0.2s;
}
.social-links a:hover {
color: #2563eb;
}
</style>
4.3 Hero 组件 #
创建 src/components/Hero.astro:
astro
---
interface Props {
title: string;
subtitle: string;
}
const { title, subtitle } = Astro.props;
---
<section class="hero">
<div class="hero-content">
<h1 class="hero-title">{title}</h1>
<p class="hero-subtitle">{subtitle}</p>
<div class="hero-actions">
<a href="/about" class="btn btn-primary">了解更多</a>
<a href="/projects" class="btn btn-secondary">查看项目</a>
</div>
</div>
</section>
<style>
.hero {
min-height: 80vh;
display: flex;
align-items: center;
justify-content: center;
text-align: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #fff;
}
.hero-content {
max-width: 800px;
padding: 2rem;
}
.hero-title {
font-size: 3rem;
margin-bottom: 1rem;
}
.hero-subtitle {
font-size: 1.25rem;
opacity: 0.9;
margin-bottom: 2rem;
}
.hero-actions {
display: flex;
gap: 1rem;
justify-content: center;
}
.btn {
padding: 0.75rem 1.5rem;
border-radius: 8px;
font-weight: 500;
transition: transform 0.2s, box-shadow 0.2s;
}
.btn:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
}
.btn-primary {
background: #fff;
color: #2563eb;
}
.btn-secondary {
background: transparent;
border: 2px solid #fff;
color: #fff;
}
</style>
五、创建页面 #
5.1 首页 #
创建 src/pages/index.astro:
astro
---
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro';
import Hero from '../components/Hero.astro';
import Footer from '../components/Footer.astro';
---
<Layout title="首页 - 我的主页">
<Header />
<main>
<Hero
title="你好,我是开发者"
subtitle="欢迎来到我的个人主页,这里展示我的作品和技能"
/>
<section class="features">
<div class="container">
<h2>我的技能</h2>
<div class="feature-grid">
<div class="feature-card">
<h3>前端开发</h3>
<p>精通 HTML、CSS、JavaScript,熟悉 React、Vue 等框架</p>
</div>
<div class="feature-card">
<h3>后端开发</h3>
<p>熟悉 Node.js、Python,有丰富的 API 开发经验</p>
</div>
<div class="feature-card">
<h3>全栈开发</h3>
<p>能够独立完成从前端到后端的完整项目开发</p>
</div>
</div>
</div>
</section>
</main>
<Footer />
</Layout>
<style>
main {
min-height: 100vh;
display: flex;
flex-direction: column;
}
.features {
padding: 4rem 2rem;
background: #f9fafb;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
.features h2 {
text-align: center;
font-size: 2rem;
margin-bottom: 2rem;
}
.feature-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
}
.feature-card {
background: #fff;
padding: 2rem;
border-radius: 12px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
}
.feature-card h3 {
color: #2563eb;
margin-bottom: 1rem;
}
</style>
5.2 关于页面 #
创建 src/pages/about.astro:
astro
---
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
const skills = [
{ name: 'JavaScript', level: 90 },
{ name: 'TypeScript', level: 85 },
{ name: 'React', level: 88 },
{ name: 'Vue', level: 80 },
{ name: 'Node.js', level: 75 },
{ name: 'Python', level: 70 },
];
---
<Layout title="关于 - 我的主页">
<Header />
<main class="main">
<section class="about-section">
<div class="container">
<h1>关于我</h1>
<div class="about-content">
<div class="about-text">
<p>
我是一名热爱编程的全栈开发者,拥有多年的 Web 开发经验。
我热衷于学习新技术,并将其应用到实际项目中。
</p>
<p>
在工作中,我注重代码质量和用户体验,致力于创建高性能、
易维护的应用程序。
</p>
</div>
<div class="skills">
<h2>技能水平</h2>
{skills.map((skill) => (
<div class="skill-item">
<div class="skill-header">
<span class="skill-name">{skill.name}</span>
<span class="skill-level">{skill.level}%</span>
</div>
<div class="skill-bar">
<div
class="skill-progress"
style={`width: ${skill.level}%`}
></div>
</div>
</div>
))}
</div>
</div>
</div>
</section>
</main>
<Footer />
</Layout>
<style>
.main {
min-height: 100vh;
padding-top: 80px;
}
.about-section {
padding: 4rem 2rem;
}
.container {
max-width: 1000px;
margin: 0 auto;
}
h1 {
font-size: 2.5rem;
margin-bottom: 2rem;
color: #1f2937;
}
.about-content {
display: grid;
gap: 3rem;
}
.about-text p {
font-size: 1.1rem;
line-height: 1.8;
color: #4b5563;
margin-bottom: 1rem;
}
.skills h2 {
font-size: 1.5rem;
margin-bottom: 1.5rem;
color: #1f2937;
}
.skill-item {
margin-bottom: 1rem;
}
.skill-header {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
}
.skill-name {
font-weight: 500;
}
.skill-level {
color: #6b7280;
}
.skill-bar {
height: 8px;
background: #e5e7eb;
border-radius: 4px;
overflow: hidden;
}
.skill-progress {
height: 100%;
background: linear-gradient(90deg, #2563eb, #7c3aed);
border-radius: 4px;
transition: width 0.5s ease;
}
</style>
5.3 项目页面 #
创建 src/pages/projects.astro:
astro
---
import Layout from '../layouts/Layout.astro';
import Header from '../components/Header.astro';
import Footer from '../components/Footer.astro';
const projects = [
{
title: '个人博客',
description: '使用 Astro 构建的个人博客网站,支持 Markdown 写作',
tags: ['Astro', 'TypeScript', 'CSS'],
link: '#',
},
{
title: '任务管理应用',
description: '基于 React 的任务管理应用,支持拖拽排序和分类管理',
tags: ['React', 'Node.js', 'MongoDB'],
link: '#',
},
{
title: '电商网站',
description: '全栈电商项目,包含商品展示、购物车、订单管理功能',
tags: ['Vue', 'Express', 'PostgreSQL'],
link: '#',
},
{
title: 'API 文档平台',
description: '在线 API 文档平台,支持交互式测试和自动生成文档',
tags: ['Next.js', 'OpenAPI', 'TypeScript'],
link: '#',
},
];
---
<Layout title="项目 - 我的主页">
<Header />
<main class="main">
<section class="projects-section">
<div class="container">
<h1>我的项目</h1>
<p class="intro">以下是我参与开发的一些项目,展示了我的技术能力和项目经验。</p>
<div class="projects-grid">
{projects.map((project) => (
<article class="project-card">
<h3 class="project-title">{project.title}</h3>
<p class="project-description">{project.description}</p>
<div class="project-tags">
{project.tags.map((tag) => (
<span class="tag">{tag}</span>
))}
</div>
<a href={project.link} class="project-link">查看详情 →</a>
</article>
))}
</div>
</div>
</section>
</main>
<Footer />
</Layout>
<style>
.main {
min-height: 100vh;
padding-top: 80px;
}
.projects-section {
padding: 4rem 2rem;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
h1 {
font-size: 2.5rem;
margin-bottom: 1rem;
color: #1f2937;
}
.intro {
color: #6b7280;
font-size: 1.1rem;
margin-bottom: 3rem;
}
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
gap: 2rem;
}
.project-card {
background: #fff;
border: 1px solid #e5e7eb;
border-radius: 12px;
padding: 1.5rem;
transition: transform 0.2s, box-shadow 0.2s;
}
.project-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1);
}
.project-title {
font-size: 1.25rem;
color: #1f2937;
margin-bottom: 0.75rem;
}
.project-description {
color: #6b7280;
line-height: 1.6;
margin-bottom: 1rem;
}
.project-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-bottom: 1rem;
}
.tag {
background: #eff6ff;
color: #2563eb;
padding: 0.25rem 0.75rem;
border-radius: 9999px;
font-size: 0.875rem;
}
.project-link {
color: #2563eb;
font-weight: 500;
display: inline-flex;
align-items: center;
transition: color 0.2s;
}
.project-link:hover {
color: #1d4ed8;
}
</style>
六、运行项目 #
6.1 启动开发服务器 #
bash
npm run dev
访问 http://localhost:4321 查看效果。
6.2 构建生产版本 #
bash
npm run build
6.3 预览构建结果 #
bash
npm run preview
七、项目总结 #
7.1 学到的知识 #
text
┌─────────────────────────────────────────────────────┐
│ 项目知识点总结 │
├─────────────────────────────────────────────────────┤
│ │
│ ✅ 布局组件的使用 │
│ └── 创建可复用的页面布局 │
│ │
│ ✅ 组件化开发 │
│ └── Header、Footer、Hero 等组件 │
│ │
│ ✅ 页面路由 │
│ └── 文件即路由,创建多页面 │
│ │
│ ✅ 样式处理 │
│ └── 组件级样式和全局样式 │
│ │
│ ✅ 数据渲染 │
│ └── 使用 map 渲染列表 │
│ │
└─────────────────────────────────────────────────────┘
7.2 下一步学习 #
下一步,让我们深入学习 组件基础!
最后更新:2026-03-28