Skip to content

个人简历站

本教程介绍如何使用 VitePress 创建一个精美的在线简历站点。

项目结构

resume/
├── docs/
│   ├── .vitepress/
│   │   └── config.mts
│   ├── public/
│   │   └── avatar.jpg
│   └── index.md
└── package.json

配置文件

ts
// docs/.vitepress/config.mts
import { defineConfig } from 'vitepress'

export default defineConfig({
  title: '张三 - 前端工程师',
  description: '3年前端开发经验,专注于 Vue 和 React',
  lang: 'zh-CN',
  
  head: [
    ['meta', { name: 'author', content: '张三' }],
    ['meta', { name: 'keywords', content: '前端,Vue,React,简历' }]
  ],
  
  themeConfig: {
    logo: '/avatar.jpg',
    
    socialLinks: [
      { icon: 'github', link: 'https://github.com/zhangsan' },
      { icon: 'linkedin', link: 'https://linkedin.com/in/zhangsan' }
    ],
    
    footer: {
      message: '欢迎联系我',
      copyright: 'Copyright © 2026'
    }
  }
})

简历首页

创建 docs/index.md

markdown
---
layout: page
---

<script setup>
import { useData } from 'vitepress'

const skills = [
  { name: 'Vue.js', level: 90 },
  { name: 'React', level: 85 },
  { name: 'TypeScript', level: 80 },
  { name: 'Node.js', level: 75 },
  { name: 'CSS', level: 90 }
]

const experiences = [
  {
    company: 'ABC 科技',
    position: '高级前端工程师',
    period: '2022.03 - 至今',
    descriptions: [
      '负责公司核心产品的前端架构设计',
      '带领 5 人团队完成多个重点项目',
      '优化首屏加载速度,提升 40%'
    ]
  },
  {
    company: 'XYZ 互联网',
    position: '前端工程师',
    period: '2020.06 - 2022.02',
    descriptions: [
      '使用 Vue 3 开发企业级管理系统',
      '封装通用组件库,提升开发效率',
      '参与前端技术选型和规范制定'
    ]
  }
]

const projects = [
  {
    name: '企业级管理后台',
    tech: 'Vue 3 + TypeScript + Vite',
    description: '企业级后台管理系统,支持权限管理、数据可视化等功能'
  },
  {
    name: '移动端电商应用',
    tech: 'React + Redux + Taro',
    description: '跨平台移动电商应用,支持微信小程序和 H5'
  }
]
</script>

<div class="resume">
  <!-- 头部信息 -->
  <header class="header">
    <img src="/avatar.jpg" alt="头像" class="avatar" />
    <div class="info">
      <h1>张三</h1>
      <p class="title">前端工程师</p>
      <div class="contact">
        <span>📧 zhangsan@email.com</span>
        <span>📱 138-xxxx-xxxx</span>
        <span>📍 北京市</span>
      </div>
    </div>
  </header>

  <!-- 个人简介 -->
  <section class="section">
    <h2>个人简介</h2>
    <p>
      3 年前端开发经验,熟悉 Vue、React 主流框架,
      具有良好的代码风格和团队协作能力。
      热爱技术,持续学习,追求卓越。
    </p>
  </section>

  <!-- 专业技能 -->
  <section class="section">
    <h2>专业技能</h2>
    <div class="skills">
      <div v-for="skill in skills" :key="skill.name" class="skill">
        <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>
  </section>

  <!-- 工作经历 -->
  <section class="section">
    <h2>工作经历</h2>
    <div class="experiences">
      <div v-for="exp in experiences" :key="exp.company" class="experience">
        <div class="experience-header">
          <h3>{{ exp.company }}</h3>
          <span class="period">{{ exp.period }}</span>
        </div>
        <p class="position">{{ exp.position }}</p>
        <ul>
          <li v-for="desc in exp.descriptions" :key="desc">{{ desc }}</li>
        </ul>
      </div>
    </div>
  </section>

  <!-- 项目经验 -->
  <section class="section">
    <h2>项目经验</h2>
    <div class="projects">
      <div v-for="project in projects" :key="project.name" class="project">
        <h3>{{ project.name }}</h3>
        <p class="tech">技术栈:{{ project.tech }}</p>
        <p>{{ project.description }}</p>
      </div>
    </div>
  </section>

  <!-- 教育背景 -->
  <section class="section">
    <h2>教育背景</h2>
    <div class="education">
      <h3>某某大学</h3>
      <p>计算机科学与技术 · 本科 · 2016-2020</p>
    </div>
  </section>
</div>

<style>
.resume {
  max-width: 800px;
  margin: 0 auto;
  padding: 40px 20px;
}

.header {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-bottom: 40px;
  padding-bottom: 24px;
  border-bottom: 2px solid var(--vp-c-divider);
}

.avatar {
  width: 120px;
  height: 120px;
  border-radius: 50%;
  object-fit: cover;
}

.info h1 {
  margin: 0;
  font-size: 32px;
}

.title {
  color: var(--vp-c-brand-1);
  font-size: 18px;
  margin: 8px 0;
}

.contact {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  color: var(--vp-c-text-2);
  font-size: 14px;
}

.section {
  margin-bottom: 32px;
}

.section h2 {
  font-size: 20px;
  border-bottom: 1px solid var(--vp-c-divider);
  padding-bottom: 8px;
  margin-bottom: 16px;
}

.skills {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.skill-header {
  display: flex;
  justify-content: space-between;
  margin-bottom: 4px;
}

.skill-bar {
  height: 8px;
  background: var(--vp-c-default-soft);
  border-radius: 4px;
  overflow: hidden;
}

.skill-progress {
  height: 100%;
  background: var(--vp-c-brand-1);
  border-radius: 4px;
}

.experience {
  margin-bottom: 24px;
}

.experience-header {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
}

.experience-header h3 {
  margin: 0;
}

.period {
  color: var(--vp-c-text-2);
  font-size: 14px;
}

.position {
  color: var(--vp-c-brand-1);
  margin: 4px 0 8px;
}

.project {
  margin-bottom: 20px;
  padding: 16px;
  background: var(--vp-c-bg-soft);
  border-radius: 8px;
}

.project h3 {
  margin: 0 0 8px;
}

.tech {
  color: var(--vp-c-text-2);
  font-size: 14px;
  margin: 0 0 8px;
}

@media (max-width: 640px) {
  .header {
    flex-direction: column;
    text-align: center;
  }
  
  .contact {
    justify-content: center;
  }
}
</style>

导出 PDF

添加打印样式:

css
/* docs/.vitepress/theme/style.css */

@media print {
  .VPNav,
  .VPSidebar,
  .VPFooter {
    display: none !important;
  }
  
  .VPContent {
    padding: 0 !important;
  }
  
  .resume {
    padding: 20px;
  }
  
  .section {
    page-break-inside: avoid;
  }
}

部署建议

平台特点
GitHub Pages免费,支持自定义域名
Vercel自动部署,全球 CDN
Netlify表单功能,易于配置

下一步

查看 知识库站点 学习搭建知识管理系统。

🎯 进阶挑战

完成基础教程后,尝试以下挑战来提升你的技能:

挑战 1:多简历模板切换 ⭐⭐⭐

目标:创建多种简历模板,支持一键切换。

提示

  • 设计 2-3 种不同风格的模板
  • 使用 CSS 变量控制主题
  • 添加模板选择器

参考思路

vue
<script setup>
const templates = ['modern', 'classic', 'minimal']
const currentTemplate = ref('modern')
</script>

<template>
  <div :class="['resume', `template-${currentTemplate}`]">
    <!-- 简历内容 -->
  </div>
</template>

挑战 2:简历数据与视图分离 ⭐⭐⭐

目标:将简历数据存储在独立文件中,便于维护。

提示

  • 创建 resume.json 数据文件
  • 使用数据加载器读取
  • 支持在线编辑预览

挑战 3:多语言简历 ⭐⭐⭐

目标:支持中英文双语简历切换。

提示

  • 使用 i18n 配置
  • 创建语言切换按钮
  • 保存语言偏好

挑战 4:在线分享链接 ⭐⭐⭐⭐

目标:生成简历的唯一分享链接。

提示

  • 使用 URL 参数存储简历 ID
  • 或使用短链接服务
  • 支持二维码生成

挑战 5:简历访问统计 ⭐⭐⭐

目标:统计简历被查看的次数和时间。

提示

  • 集成分析工具(如 Umami)
  • 记录访问来源
  • 可视化展示数据

挑战 6:简历版本管理 ⭐⭐⭐⭐

目标:支持保存多个版本的简历。

提示

  • 使用 localStorage 存储多个版本
  • 创建版本列表管理
  • 支持版本对比和回滚

贡献者

加载中...

想要成为贡献者?

在 CNB 上参与贡献