『AI 编程』用 Claude Code 从零到一开发全栈减脂追踪应用

最近体验了 Claude Code AI 编程工具,用了不到半天就完成了一个功能完善的减脂追踪系统。从需求确认到部署上线,整个过程让我对 AI 辅助编程有了全新的认识。

为什么做这个项目

作为一个程序员,长期久坐让我意识到健康管理的重要性。想要科学减脂,但市面上的健身 App 要么功能臃肿,要么需要联网注册,数据隐私得不到保障。于是萌生了自己开发一个纯前端、离线可用、数据完全本地存储的减脂追踪工具的想法。

正好最近在关注 AI 编程工具,听说 Claude Code 在代码生成和问题解决方面表现不错,就决定用它来试试能否快速实现这个项目。

项目在线体验 : cloud1-0gjwj0rtfea6f3d4-1252084777.tcloudbaseapp.com/


为什么选择 Claude Code

在尝试 Claude Code 之前,我也用过 GitHub Copilot、ChatGPT 等工具。Claude Code 给我最大的感受是:

  1. 上下文理解能力强: 能够理解整个项目结构,而不仅仅是当前文件
  2. 代码质量高: 生成的代码符合最佳实践,很少需要大幅修改
  3. 问题定位准确: 遇到 Bug 时能快速定位问题所在
  4. 交互体验好: 可以像和同事交流一样,用自然语言描述需求

特别是当我说"我想实现一个响应式的仪表盘,要包含今日任务、训练统计、关键指标等模块",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 实现的打卡流程:

  1. 自动获取今日计划 (trainingStore.getTodayPlans())
  2. 打卡按钮 → 弹出对话框
  3. 填写训练详情 → 保存记录
  4. 实时更新完成率统计

截图展示:

核心逻辑:

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 部署步骤

  1. 安装 CloudBase CLI:
bash 复制代码
npm install -g @cloudbase/cli
  1. 登录并初始化:
bash 复制代码
cloudbase login
cloudbase init
  1. 配置 cloudbaserc.json:
json 复制代码
{
  "envId": "cloud1-0gjwj0rtfea6f3d4",
  "framework": {
    "name": "FatLossTracker",
    "plugins": {
      "client": {
        "use": "@cloudbase/framework-plugin-website",
        "inputs": {
          "buildCommand": "npm run build",
          "outputPath": "dist",
          "cloudPath": "/"
        }
      }
    }
  }
}
  1. 部署:
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. 明确需求描述

不好的描述:

"做一个训练计划页面"

好的描述:

"实现一个训练计划管理页面,需要:

  1. 列表展示所有计划 (卡片式布局)
  2. 支持添加新计划 (对话框表单)
  3. 支持编辑和删除 (确认对话框)
  4. 支持启用/禁用开关
  5. 显示计划详情 (运动类型、时长、频率)"

具体的描述能让 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. 分阶段迭代,不要贪多

不要一次性提出所有需求,而是:

  1. 先实现核心功能
  2. 测试验证
  3. 再添加优化功能

这样可以避免代码过于复杂,也便于调试。

4. 代码审查,不要盲目信任

AI 生成的代码不一定是最优的,你需要:

  • 检查边界情况
  • 优化性能瓶颈
  • 统一代码风格
  • 补充单元测试

5. 善用 AI,不要依赖 AI

AI 是工具,不是拐杖。要:

  • 用 AI 提高效率,而不是替代思考
  • 用 AI 学习新知识,而不是复制粘贴
  • 用 AI 解决问题,而不是逃避问题

结语

这次使用 Claude Code 开发减脂追踪系统的经历,让我对 AI 编程工具有了全新的认识。它不仅提高了我的开发效率,还让我学到了很多新技术,更重要的是让我重新思考了"编程"这件事的本质。

编程的本质不是写代码,而是解决问题。AI 工具帮我们写代码,让我们有更多时间去思考"要解决什么问题"、"如何更好地解决问题",这才是编程的核心价值。

如果你也对 AI 编程感兴趣,不妨试试 Claude Code,相信你会有和我一样的惊喜!


项目资源


相关推荐
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅7 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅8 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊8 小时前
jwt介绍
前端
爱敲代码的小鱼8 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax