最近体验了 Claude Code AI 编程工具,用了不到半天就完成了一个功能完善的减脂追踪系统。从需求确认到部署上线,整个过程让我对 AI 辅助编程有了全新的认识。
为什么做这个项目
作为一个程序员,长期久坐让我意识到健康管理的重要性。想要科学减脂,但市面上的健身 App 要么功能臃肿,要么需要联网注册,数据隐私得不到保障。于是萌生了自己开发一个纯前端、离线可用、数据完全本地存储的减脂追踪工具的想法。
正好最近在关注 AI 编程工具,听说 Claude Code 在代码生成和问题解决方面表现不错,就决定用它来试试能否快速实现这个项目。
项目在线体验 : cloud1-0gjwj0rtfea6f3d4-1252084777.tcloudbaseapp.com/
为什么选择 Claude Code
在尝试 Claude Code 之前,我也用过 GitHub Copilot、ChatGPT 等工具。Claude Code 给我最大的感受是:
- 上下文理解能力强: 能够理解整个项目结构,而不仅仅是当前文件
- 代码质量高: 生成的代码符合最佳实践,很少需要大幅修改
- 问题定位准确: 遇到 Bug 时能快速定位问题所在
- 交互体验好: 可以像和同事交流一样,用自然语言描述需求
特别是当我说"我想实现一个响应式的仪表盘,要包含今日任务、训练统计、关键指标等模块",Claude Code 不仅能理解我的意图,还会主动建议最佳的实现方案和组件库选择。
开发全流程实录
需求确认阶段
第一步:明确核心功能
我先和 Claude Code 进行了一轮"需求对话":
我: "我想做一个减脂追踪系统,需要哪些核心功能?"
Claude: (总结了用户画像、核心场景、必需功能)
- 用户设置 (身高、体重、目标)
- 训练计划管理 (根据 BMI 智能生成)
- 每日打卡系统
- 体重/腰围/体脂记录
- 数据可视化统计
- 数据导入导出
这个回答让我眼前一亮 ------ 智能生成训练计划这个点我原本没想到,但确实很实用!
第二步:确定技术约束
我: "我希望数据完全本地存储,不依赖后端,用什么技术栈比较好?"
Claude:
- 前端框架: Vue 3 (Composition API + TypeScript)
- UI 组件库: Element Plus
- 状态管理: Pinia
- 数据存储: LocalStorage
- 图表库: ECharts
- 构建工具: Vite
这个技术栈非常符合我的需求,而且 Claude Code 还贴心地解释了每个选型的理由。
技术选型
确定技术栈后,Claude Code 帮我快速初始化了项目:
bash
npm create vite@latest FatLossTracker -- --template vue-ts
cd FatLossTracker
npm install
然后一键安装依赖:
bash
npm install vue-router@4 pinia element-plus @element-plus/icons-vue echarts dayjs sass
项目结构也是 Claude Code 建议的:
bash
src/
├── views/ # 页面组件
├── store/ # Pinia 状态管理
├── router/ # 路由配置
├── utils/ # 工具函数
├── types/ # TypeScript 类型
├── components/ # 公共组件
└── styles/ # 全局样式
这套结构清晰明了,后续维护也很方便。
代码开发
阶段一:搭建基础架构
Claude Code 先帮我实现了整体布局 App.vue
,包括:
- 侧边栏导航 (渐变紫色背景)
- 主内容区域 (路由视图)
- 响应式布局 (移动端抽屉菜单)
关键代码:
vue
<!-- App.vue -->
<template>
<el-container class="app-container">
<!-- 侧边栏 -->
<el-aside class="sidebar" width="250px">
<div class="logo">
<el-icon><TrendCharts /></el-icon>
<span>减脂追踪</span>
</div>
<el-menu router :default-active="currentRoute">
<el-menu-item index="/">
<el-icon><Odometer /></el-icon>
<span>仪表盘</span>
</el-menu-item>
<!-- 更多菜单项... -->
</el-menu>
</el-aside>
<!-- 主内容区 -->
<el-main class="main-content">
<router-view v-slot="{ Component }">
<transition name="fade">
<component :is="Component" />
</transition>
</router-view>
</el-main>
</el-container>
</template>
阶段二:实现核心功能
1. 用户设置页面 (Settings.vue
)
需求描述: "实现一个用户设置页面,包含基本信息表单、健康数据计算、数据导入导出功能"
Claude Code 生成的代码包含:
- 表单验证 (Element Plus Form Rules)
- BMI/BMR/TDEE 自动计算
- 建议卡路里显示
- 一键生成训练计划按钮
- 数据导入导出功能
截图展示:
这个页面的表单验证逻辑特别完善,比如:
typescript
const rules = reactive<FormRules>({
name: [{ required: true, message: '请输入姓名', trigger: 'blur' }],
height: [
{ required: true, message: '请输入身高', trigger: 'blur' },
{ type: 'number', min: 100, max: 250, message: '身高应在100-250cm之间', trigger: 'blur' }
],
// 更多验证规则...
})
2. 训练计划管理 (TrainingPlan.vue
)
需求描述: "训练计划要支持增删改查,可以设置星期几训练,包含有氧和无氧两种类型"
Claude Code 实现了:
- 计划列表展示 (卡片式布局)
- 启用/禁用开关
- 编辑对话框 (支持多选星期、时段、运动项目)
- 删除确认
截图展示:

特别值得一提的是智能计划生成算法 (utils/planGenerator.ts
):
typescript
export function generateDefaultPlans(profile: UserProfile): TrainingPlan[] {
const bmi = calculateBMI(profile.currentWeight, profile.height)
const isOverweight = bmi >= 24
// 超重用户生成较短时长的有氧计划
const aerobicDuration = isOverweight ? 25 : 30
const plans: TrainingPlan[] = [
{
name: '有氧运动',
type: 'aerobic',
dayOfWeek: [1, 3, 5], // 周一三五
timeSlot: 'evening',
duration: aerobicDuration,
exercises: [{ name: '椭圆机', duration: aerobicDuration }],
enabled: true
},
// 上肢力量、下肢核心...
]
return plans
}
这段代码展示了 Claude Code 的智能之处:根据用户 BMI 自动调整训练强度,非常人性化!
3. 打卡中心 (CheckIn.vue
)
需求描述: "显示今天的训练计划,可以打卡完成,记录实际时长、强度评分、训练感受"
Claude Code 实现的打卡流程:
- 自动获取今日计划 (
trainingStore.getTodayPlans()
) - 打卡按钮 → 弹出对话框
- 填写训练详情 → 保存记录
- 实时更新完成率统计
截图展示:

核心逻辑:
typescript
// store/training.ts
getTodayPlans() {
const today = dayjs()
const dayOfWeek = today.day() || 7 // 0-6 转为 1-7
return this.plans.filter(plan =>
plan.enabled && plan.dayOfWeek.includes(dayOfWeek)
)
}
4. 身体数据记录 (BodyData.vue
)
需求描述: "支持快速记录(只填体重)和详细记录(体重+腰围+体脂),BMI 自动计算"
Claude Code 设计了两种录入模式:
- 快速记录: 一键输入今日体重
- 详细记录: 表单录入完整数据
截图展示:

自动计算 BMI:
typescript
const addRecord = () => {
const bmi = calculateBMI(form.weight, userStore.profile.height)
bodyDataStore.addRecord({
date: form.date,
time: form.time,
weight: form.weight,
waistline: form.waistline,
bodyFat: form.bodyFat,
bmi: bmi,
notes: form.notes
})
// 同步更新用户当前体重
userStore.updateCurrentWeight(form.weight)
}
5. 数据统计 (Statistics.vue
)
需求描述: "用 ECharts 展示体重趋势、BMI 趋势、训练时长、类型分布等数据"
这是 Claude Code 表现最亮眼的地方!我只是简单描述了需求,它就生成了完整的图表配置:
体重趋势图:
typescript
const weightOption = {
title: { text: '体重变化趋势' },
tooltip: { trigger: 'axis' },
xAxis: {
type: 'category',
data: dateList,
axisLabel: { rotate: 45 }
},
yAxis: {
type: 'value',
name: '体重 (kg)',
min: (value) => Math.floor(value.min - 2),
max: (value) => Math.ceil(value.max + 2)
},
series: [{
name: '体重',
type: 'line',
data: weightList,
smooth: true,
lineStyle: { color: '#409EFF', width: 3 },
areaStyle: {
color: {
type: 'linear',
x: 0, y: 0, x2: 0, y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(64, 158, 255, 0.3)' },
{ offset: 1, color: 'rgba(64, 158, 255, 0.05)' }
]
}
}
}]
}
截图展示:

图表配置非常专业:
- 渐变色填充
- 平滑曲线
- 坐标轴自适应
- 响应式布局
6. 仪表盘 (Dashboard.vue
)
需求描述: "做一个综合概览页面,包含今日任务、本周数据、关键指标等模块"
Claude Code 设计了一个非常精美的 Dashboard:
- 个性化问候: 根据时间显示"早上好/下午好/晚上好"
- 减重进度条: 可视化展示减重进度
- 快捷入口: 卡片式布局,点击跳转到各个功能页面
- 今日任务: 显示今天的训练计划和完成率
- 本周数据: 训练次数、总时长、平均时长
- 关键指标: 连续打卡天数、总训练次数、平均完成率
截图展示:

减重进度计算:
typescript
const lostWeight = computed(() =>
userStore.profile.initialWeight - userStore.profile.currentWeight
)
const targetWeight = computed(() =>
userStore.profile.initialWeight - userStore.profile.targetWeight
)
const progress = computed(() => {
if (targetWeight.value <= 0) return 0
return Math.min((lostWeight.value / targetWeight.value) * 100, 100)
})
阶段三:优化体验
1. 响应式适配
需求描述: "需要支持移动端访问,断点设为 768px"
Claude Code 自动为所有页面添加了响应式支持:
移动端导航:
vue
<!-- 移动端顶部栏 -->
<div class="mobile-header" v-if="isMobile">
<el-button @click="drawerVisible = true">
<el-icon><Menu /></el-icon>
</el-button>
<span class="page-title">{{ currentPageTitle }}</span>
<ThemeToggle />
</div>
<!-- 抽屉式侧边栏 -->
<el-drawer v-model="drawerVisible" direction="ltr" :size="250">
<el-menu router :default-active="currentRoute">
<!-- 菜单项 -->
</el-menu>
</el-drawer>
栅格响应式布局:
vue
<el-row :gutter="20">
<el-col :xs="24" :sm="12" :md="8" :lg="6">
<el-card>快捷入口卡片</el-card>
</el-col>
</el-row>
截图展示 :


2. 深色模式支持
需求描述: "添加深色模式,主题切换要有精美的动画效果"
Claude Code 实现了一个非常炫酷的主题切换动画:
太阳图标 (浅色模式):
- 金黄色
- 光芒旋转动画 (20秒/圈)
月亮图标 (深色模式):
- 银灰色
- 三颗星星闪烁 (2秒周期,错开延迟)
切换过渡:
- 旋转 180°
- 缩放变化
- 透明度渐变
- 贝塞尔曲线缓动 (0.5秒)
关键代码:
scss
// 太阳图标样式
.theme-icon.sun {
color: #f39c12;
.rays {
animation: rotate 20s linear infinite;
}
}
// 月亮图标样式
.theme-icon.moon {
color: #bdc3c7;
.star {
animation: twinkle 2s ease-in-out infinite;
&:nth-child(2) { animation-delay: 0.5s; }
&:nth-child(3) { animation-delay: 1s; }
}
}
@keyframes rotate {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
@keyframes twinkle {
0%, 100% { opacity: 1; }
50% { opacity: 0.3; }
}
截图展示:


3. 性能优化
需求描述: "优化加载性能,图表要懒加载,表格要分页"
Claude Code 帮我实现了多项性能优化:
图表懒加载 (使用 Intersection Observer):
typescript
// composables/useIntersectionObserver.ts
export function useIntersectionObserver(
target: Ref<HTMLElement | null>,
callback: () => void
) {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
callback()
observer.disconnect()
}
})
},
{
rootMargin: '50px',
threshold: 0.1
}
)
onMounted(() => {
if (target.value) {
observer.observe(target.value)
}
})
onUnmounted(() => {
observer.disconnect()
})
}
使用方式:
typescript
const chartRef = ref<HTMLElement | null>(null)
useIntersectionObserver(chartRef, () => {
nextTick(() => initChart())
})
表格分页:
vue
<el-table :data="pagedRecords" max-height="600">
<!-- 表格列 -->
</el-table>
<el-pagination
v-model:current-page="currentPage"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50, 100]"
:total="totalRecords"
layout="total, sizes, prev, pager, next, jumper"
/>
4. PWA 支持
需求描述: "希望应用可以安装到桌面,支持离线使用"
Claude Code 帮我配置了完整的 PWA 功能:
安装插件:
bash
npm install vite-plugin-pwa -D
Vite 配置 (vite.config.ts
):
typescript
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
vue(),
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['icon.svg', 'icon-192x192.svg', 'icon-512x512.svg'],
manifest: {
name: '减脂追踪系统',
short_name: '减脂追踪',
description: '个人减脂计划与进度追踪应用',
theme_color: '#667eea',
background_color: '#ffffff',
display: 'standalone',
icons: [
{
src: 'icon-192x192.svg',
sizes: '192x192',
type: 'image/svg+xml'
},
{
src: 'icon-512x512.svg',
sizes: '512x512',
type: 'image/svg+xml'
}
]
},
workbox: {
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-cache',
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365 // 1 年
}
}
}
],
cleanupOutdatedCaches: true
}
})
]
})
效果:
- ✅ 可安装到桌面/主屏幕
- ✅ 离线访问
- ✅ 自动更新
- ✅ 独立窗口运行
测试验证
完成开发后,我进行了全面的功能测试:
功能测试清单
功能模块 | 测试项 | 结果 |
---|---|---|
用户设置 | 表单验证、数据保存、计算准确性 | ✅ 通过 |
训练计划 | 增删改查、启用禁用、智能生成 | ✅ 通过 |
打卡系统 | 今日计划获取、打卡记录、完成率统计 | ✅ 通过 |
身体数据 | 快速记录、详细记录、BMI 计算 | ✅ 通过 |
数据统计 | 图表展示、数据筛选、趋势分析 | ✅ 通过 |
仪表盘 | 数据汇总、快捷入口、进度展示 | ✅ 通过 |
响应式 | 移动端适配、抽屉菜单、触摸交互 | ✅ 通过 |
主题切换 | 深色模式、动画效果、状态持久化 | ✅ 通过 |
PWA | 安装、离线使用、自动更新 | ✅ 通过 |
兼容性测试
平台 | 浏览器 | 版本 | 结果 |
---|---|---|---|
macOS | Chrome | 120+ | ✅ 完美 |
macOS | Safari | 17+ | ✅ 完美 |
iOS | Safari | 16+ | ✅ 完美 |
Android | Chrome | 120+ | ✅ 完美 |
Windows | Edge | 120+ | ✅ 完美 |
部署上线
最后一步是部署到云端。我尝试了几种方案:
方案对比
平台 | 优点 | 缺点 | 结果 |
---|---|---|---|
Vercel | 部署简单、速度快 | 国内访问不稳定 | ❌ 放弃 |
Cloudflare Pages | 全球 CDN、免费额度高 | 构建时间稍长 | ⚠️ 备选 |
腾讯云 CloudBase | 国内访问快、稳定 | 免费额度有限 | ✅ 最终选择 |
腾讯云 CloudBase 部署步骤
- 安装 CloudBase CLI:
bash
npm install -g @cloudbase/cli
- 登录并初始化:
bash
cloudbase login
cloudbase init
- 配置
cloudbaserc.json
:
json
{
"envId": "cloud1-0gjwj0rtfea6f3d4",
"framework": {
"name": "FatLossTracker",
"plugins": {
"client": {
"use": "@cloudbase/framework-plugin-website",
"inputs": {
"buildCommand": "npm run build",
"outputPath": "dist",
"cloudPath": "/"
}
}
}
}
}
- 部署:
bash
npm run build
cloudbase framework deploy
部署成功!
访问地址: cloud1-0gjwj0rtfea6f3d4-1252084777.tcloudbaseapp.com/
项目主要功能
1. 智能训练计划生成
根据用户的 BMI、年龄、性别,自动生成科学的训练计划:
- 超重用户 (BMI ≥ 24): 较短时长的有氧运动,避免运动损伤
- 正常体重: 有氧 + 无氧结合,塑造体型
- 自动分配频率: 周一三五有氧,周二四力量,周六核心
这个功能是 Claude Code 建议的,实际使用中非常实用!
2. 完善的打卡系统
- 今日任务: 自动显示今天的训练计划
- 打卡记录: 记录实际时长、强度评分 (1-5)、训练感受
- 统计分析: 连续打卡天数、本周完成率、总训练时长
3. 身体数据追踪
- 多时段记录: 早上/晚上两次测量
- 多维度数据: 体重、腰围、体脂率
- 自动计算: BMI 自动计算并分级 (偏瘦/正常/超重/肥胖)
- 趋势分析: 7/30/90 天体重变化曲线
4. 数据可视化
使用 ECharts 实现了 4 种图表:
- 体重趋势图: 折线图 + 渐变填充
- BMI 趋势图: 带标准线的折线图
- 训练时长图: 最近 30 天柱状图
- 训练类型分布: 饼图
所有图表支持:
- 响应式布局
- 懒加载 (Intersection Observer)
- 深色模式适配
5. 健康数据计算
- BMI: 体重指数
- BMR: 基础代谢率 (Mifflin-St Jeor 公式)
- TDEE: 每日总消耗 (考虑活动水平)
- 建议卡路里: 减重建议摄入量 (TDEE - 500)
公式都是 Claude Code 提供的,非常专业!
6. 数据导入导出
- 导出: 一键导出所有数据为 JSON 文件
- 导入: 支持恢复备份数据
- 数据隔离: 仅导出本应用数据,不影响其他应用的 LocalStorage
7. 响应式设计
- 断点: 768px (移动端/桌面端)
- 移动端特性 :
- 抽屉式侧边栏
- 全屏对话框
- 触摸友好的按钮
- 表格横向滚动
8. 深色模式
- 自动记忆: 主题选择保存在 LocalStorage
- 精美动画 :
- 太阳光芒旋转 (20秒/圈)
- 月亮星星闪烁 (2秒周期)
- 切换旋转缩放效果 (0.5秒)
9. PWA 支持
- 可安装: 添加到桌面/主屏幕
- 离线使用: Service Worker 缓存
- 自动更新: 检测新版本并提示
- 独立窗口: 全屏应用体验
技术亮点
1. 纯前端架构
- 无后端依赖: 所有数据存储在 LocalStorage
- 隐私保护: 数据完全本地,不上传服务器
- 快速响应: 无网络请求延迟
2. TypeScript 类型安全
所有数据结构都有明确的类型定义:
typescript
// types/index.ts
export interface UserProfile {
name: string
gender: 'male' | 'female'
age: number
height: number
initialWeight: number
currentWeight: number
targetWeight: number
targetDate: string
activityLevel: 'low' | 'medium' | 'high'
createdAt: string
}
export interface TrainingPlan {
id: string
name: string
type: 'aerobic' | 'anaerobic'
dayOfWeek: number[] // 1=周一 7=周日
timeSlot: 'morning' | 'afternoon' | 'evening'
duration: number
exercises: Exercise[]
enabled: boolean
createdAt: string
}
export interface CheckInRecord {
id: string
date: string // YYYY-MM-DD
planId: string
completed: boolean
actualDuration?: number
intensity?: 1 | 2 | 3 | 4 | 5
notes?: string
createdAt: string
}
export interface BodyRecord {
id: string
date: string // YYYY-MM-DD
time: 'morning' | 'evening'
weight: number
waistline?: number
bodyFat?: number
bmi: number
notes?: string
createdAt: string
}
这套类型系统让代码非常健壮,基本杜绝了运行时错误。
3. Pinia 状态管理
使用 4 个独立的 Store:
- userStore: 用户信息、减重进度计算
- trainingStore: 训练计划、打卡记录、统计数据
- bodyDataStore: 体重记录、BMI 计算、趋势分析
- themeStore: 主题模式
每个 Store 都有 init()
方法从 LocalStorage 加载数据:
typescript
// store/user.ts
export const useUserStore = defineStore('user', () => {
const profile = reactive<UserProfile | null>(null)
const init = () => {
const data = loadFromStorage('user_profile')
if (data) {
Object.assign(profile, data)
}
}
const saveProfile = (data: UserProfile) => {
Object.assign(profile, data)
saveToStorage('user_profile', profile)
}
return { profile, init, saveProfile }
})
4. 计算属性优化
大量使用 computed
避免重复计算:
typescript
// Dashboard.vue
const lostWeight = computed(() =>
userStore.profile.initialWeight - userStore.profile.currentWeight
)
const progress = computed(() => {
const target = userStore.profile.initialWeight - userStore.profile.targetWeight
if (target <= 0) return 0
return Math.min((lostWeight.value / target) * 100, 100)
})
const remainingWeight = computed(() =>
Math.max(userStore.profile.currentWeight - userStore.profile.targetWeight, 0)
)
5. Composable 复用逻辑
封装了常用逻辑为 Composable:
typescript
// composables/useIntersectionObserver.ts
export function useIntersectionObserver(
target: Ref<HTMLElement | null>,
callback: () => void,
options?: IntersectionObserverInit
) {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
callback()
observer.disconnect()
}
})
},
{
rootMargin: '50px',
threshold: 0.1,
...options
}
)
onMounted(() => {
if (target.value) {
observer.observe(target.value)
}
})
onUnmounted(() => {
observer.disconnect()
})
}
使用方式:
typescript
const chartRef = ref<HTMLElement | null>(null)
useIntersectionObserver(chartRef, initChart)
6. 工具函数封装
将业务逻辑抽离为纯函数,易于测试和复用:
typescript
// utils/calculator.ts
export function calculateBMI(weight: number, height: number): number {
const heightInMeters = height / 100
return parseFloat((weight / (heightInMeters * heightInMeters)).toFixed(1))
}
export function calculateBMR(
weight: number,
height: number,
age: number,
gender: 'male' | 'female'
): number {
if (gender === 'male') {
return 10 * weight + 6.25 * height - 5 * age + 5
} else {
return 10 * weight + 6.25 * height - 5 * age - 161
}
}
export function calculateTDEE(
bmr: number,
activityLevel: 'low' | 'medium' | 'high'
): number {
const multipliers = {
low: 1.375,
medium: 1.55,
high: 1.725
}
return Math.round(bmr * multipliers[activityLevel])
}
// utils/planGenerator.ts
export function generateDefaultPlans(profile: UserProfile): TrainingPlan[] {
const bmi = calculateBMI(profile.currentWeight, profile.height)
const isOverweight = bmi >= 24
const aerobicDuration = isOverweight ? 25 : 30
return [
{
id: generateId(),
name: '有氧运动',
type: 'aerobic',
dayOfWeek: [1, 3, 5],
timeSlot: 'evening',
duration: aerobicDuration,
exercises: [{ name: '椭圆机', duration: aerobicDuration }],
enabled: true,
createdAt: new Date().toISOString()
},
// 更多计划...
]
}
// utils/storage.ts
export const APP_STORAGE_KEYS = {
USER_PROFILE: 'user_profile',
TRAINING_PLANS: 'training_plans',
CHECKIN_RECORDS: 'checkin_records',
BODY_RECORDS: 'body_records',
THEME_MODE: 'theme_mode'
} as const
export function saveToStorage(key: string, data: any) {
try {
localStorage.setItem(key, JSON.stringify(data))
} catch (error) {
console.error('存储失败:', error)
}
}
export function loadFromStorage<T>(key: string): T | null {
try {
const data = localStorage.getItem(key)
return data ? JSON.parse(data) : null
} catch (error) {
console.error('读取失败:', error)
return null
}
}
export function exportAllData(): string {
const data = {
user_profile: loadFromStorage(APP_STORAGE_KEYS.USER_PROFILE),
training_plans: loadFromStorage(APP_STORAGE_KEYS.TRAINING_PLANS),
checkin_records: loadFromStorage(APP_STORAGE_KEYS.CHECKIN_RECORDS),
body_records: loadFromStorage(APP_STORAGE_KEYS.BODY_RECORDS)
}
return JSON.stringify(data, null, 2)
}
7. 性能优化策略
- 路由懒加载: 所有页面组件按需加载
- 图表懒加载: Intersection Observer 检测可见性
- 表格分页: 避免一次渲染大量数据
- 事件监听器清理 :
onUnmounted
中移除监听器 - ECharts 实例销毁: 防止内存泄漏
typescript
// 路由懒加载
const routes = [
{
path: '/',
component: () => import('@/views/Dashboard.vue')
},
{
path: '/training-plan',
component: () => import('@/views/TrainingPlan.vue')
}
]
// 图表懒加载
const chartRef = ref<HTMLElement | null>(null)
let chart: echarts.ECharts | null = null
useIntersectionObserver(chartRef, () => {
nextTick(() => initChart())
})
const initChart = () => {
chart = echarts.init(chartRef.value)
chart.setOption(option)
const handleResize = () => chart?.resize()
window.addEventListener('resize', handleResize)
onUnmounted(() => {
window.removeEventListener('resize', handleResize)
chart?.dispose()
})
}
8. CSS 变量主题系统
使用 CSS 变量实现主题切换,无需重新加载页面:
scss
// styles/theme.scss
:root {
/* 浅色模式 */
--color-bg-page: #f5f7fa;
--color-bg-container: #ffffff;
--color-text-primary: #303133;
--color-text-secondary: #909399;
--color-border: #dcdfe6;
--color-sidebar: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
[data-theme='dark'] {
/* 深色模式 */
--color-bg-page: #1a1a1a;
--color-bg-container: #2c2c2c;
--color-text-primary: #e0e0e0;
--color-text-secondary: #a0a0a0;
--color-border: #404040;
--color-sidebar: linear-gradient(135deg, #434343 0%, #000000 100%);
}
.app-container {
background-color: var(--color-bg-page);
color: var(--color-text-primary);
}
切换主题只需改变 data-theme
属性:
typescript
// store/theme.ts
export const useThemeStore = defineStore('theme', () => {
const mode = ref<'light' | 'dark'>('light')
const toggleTheme = () => {
mode.value = mode.value === 'light' ? 'dark' : 'light'
document.documentElement.setAttribute('data-theme', mode.value)
saveToStorage('theme_mode', mode.value)
}
return { mode, toggleTheme }
})
Claude Code 使用心得
经过一周的深度使用,我总结了 Claude Code 的优缺点和最佳实践。
优点
1. 上下文理解能力强
Claude Code 能够理解整个项目的结构和设计意图,而不仅仅是当前文件。
2. 代码质量高
生成的代码符合最佳实践:
- TypeScript 类型安全
- Vue 3 Composition API
- 响应式数据处理
- 错误处理完善
- 代码注释清晰
很少需要大幅修改,通常只需微调参数。
3. 问题定位准确
遇到 Bug 时,Claude Code 能快速定位问题。
4. 主动提出优化建议
Claude Code 不仅实现需求,还会主动建议优化方案:
- "这个图表可以用懒加载优化性能"
- "建议添加表格分页,避免一次渲染大量数据"
- "可以封装一个 Composable 复用这个逻辑"
这些建议都非常实用,让项目质量提升了一个档次。
5. 文档和注释完善
生成的代码都有清晰的注释:
typescript
/**
* 计算基础代谢率 (BMR)
* 使用 Mifflin-St Jeor 公式
* @param weight 体重 (kg)
* @param height 身高 (cm)
* @param age 年龄
* @param gender 性别
* @returns BMR (千卡/天)
*/
export function calculateBMR(
weight: number,
height: number,
age: number,
gender: 'male' | 'female'
): number {
if (gender === 'male') {
return 10 * weight + 6.25 * height - 5 * age + 5
} else {
return 10 * weight + 6.25 * height - 5 * age - 161
}
}
这种注释不仅说明了函数功能,还标注了使用的算法,非常贴心。
最佳实践
1. 明确需求描述
不好的描述:
"做一个训练计划页面"
好的描述:
"实现一个训练计划管理页面,需要:
- 列表展示所有计划 (卡片式布局)
- 支持添加新计划 (对话框表单)
- 支持编辑和删除 (确认对话框)
- 支持启用/禁用开关
- 显示计划详情 (运动类型、时长、频率)"
具体的描述能让 Claude Code 生成更符合预期的代码。
2. 分阶段开发
不要一次性提出所有需求,而是分阶段迭代:
第一阶段 : 基础功能 (增删改查) 第二阶段 : 优化体验 (响应式、动画) 第三阶段: 性能优化 (懒加载、缓存)
这样可以避免代码过于复杂,也便于测试和调试。
3. 及时反馈问题
遇到不符合预期的代码,及时和 Claude Code 沟通:
案例:
"生成的图表在移动端显示不全,能帮忙优化一下吗?"
Claude Code 会立即修复问题,并解释原因。
4. 利用项目文档
我在项目根目录创建了 CLAUDE.md
文件,记录了:
- 项目概述
- 技术栈
- 目录结构
- 开发规范
- 常用命令
这样 Claude Code 就能更好地理解项目上下文,生成的代码更加一致。
5. 定期代码审查
虽然 Claude Code 生成的代码质量很高,但还是要定期审查:
- 检查边界情况
- 优化性能瓶颈
- 统一代码风格
- 补充单元测试
总结与展望
代码质量提升
Claude Code 生成的代码质量非常高:
- TypeScript 类型安全
- 符合 Vue 3 最佳实践
- 错误处理完善
- 注释清晰易懂
这让我可以把更多精力放在业务逻辑和用户体验上,而不是纠结于代码细节。
学习新技术
在开发过程中,我学到了很多新知识:
- Pinia 状态管理: 比 Vuex 更简洁
- ECharts 图表: 强大的数据可视化能力
- PWA 技术: 让 Web 应用体验接近原生
- Intersection Observer: 实现高性能懒加载
- CSS 变量: 优雅的主题切换方案
这些都是 Claude Code 在实现功能时引入的,让我的技术栈更加完善。
未来计划
虽然项目已经基本完成,但还有一些功能可以优化:
对 AI 编程的思考
通过这个项目,我对 AI 编程工具有了更深的理解:
AI 能做什么
- ✅ 快速搭建项目架构
- ✅ 生成高质量的业务代码
- ✅ 快速定位和修复 Bug
- ✅ 提供优化建议
- ✅ 解释复杂算法和概念
AI 不能做什么
- ❌ 完全理解用户需求 (需要人类明确描述)
- ❌ 做出产品决策 (功能优先级、设计风格)
- ❌ 保证代码 100% 正确 (需要测试和审查)
- ❌ 替代人类的创造力 (独特的 UX 设计、创新的解决方案)
最佳协作模式
我认为最理想的开发模式是:
人类负责:
- 需求分析和产品设计
- 技术选型和架构设计
- 代码审查和质量把控
- 用户体验优化
AI 负责:
- 搭建项目基础架构
- 生成业务功能代码
- 修复常规 Bug
- 提供优化建议
这种"人类出创意,AI 出代码"的协作模式,能最大化双方的优势。
给想尝试 AI 编程的朋友的建议
1. 先学基础,再用 AI
AI 工具虽然强大,但不能替代基础知识。你需要:
- 理解编程语言的基本语法
- 掌握框架的核心概念
- 能够阅读和理解代码
- 具备基本的调试能力
有了这些基础,你才能判断 AI 生成的代码是否正确,是否符合需求。
2. 明确需求,具体描述
AI 不会读心术,你需要明确告诉它:
- 要实现什么功能
- 要达到什么效果
- 有什么约束条件
描述越具体,AI 生成的代码越符合预期。
3. 分阶段迭代,不要贪多
不要一次性提出所有需求,而是:
- 先实现核心功能
- 测试验证
- 再添加优化功能
这样可以避免代码过于复杂,也便于调试。
4. 代码审查,不要盲目信任
AI 生成的代码不一定是最优的,你需要:
- 检查边界情况
- 优化性能瓶颈
- 统一代码风格
- 补充单元测试
5. 善用 AI,不要依赖 AI
AI 是工具,不是拐杖。要:
- 用 AI 提高效率,而不是替代思考
- 用 AI 学习新知识,而不是复制粘贴
- 用 AI 解决问题,而不是逃避问题
结语
这次使用 Claude Code 开发减脂追踪系统的经历,让我对 AI 编程工具有了全新的认识。它不仅提高了我的开发效率,还让我学到了很多新技术,更重要的是让我重新思考了"编程"这件事的本质。
编程的本质不是写代码,而是解决问题。AI 工具帮我们写代码,让我们有更多时间去思考"要解决什么问题"、"如何更好地解决问题",这才是编程的核心价值。
如果你也对 AI 编程感兴趣,不妨试试 Claude Code,相信你会有和我一样的惊喜!
项目资源
- 在线体验 : cloud1-0gjwj0rtfea6f3d4-1252084777.tcloudbaseapp.com/
- 技术栈: Vue 3 + TypeScript + Vite + Element Plus + Pinia + ECharts + PWA
- 开发工具: Claude Code by Anthropic