『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,相信你会有和我一样的惊喜!


项目资源


相关推荐
tyro曹仓舒2 小时前
Vue单文件组件到底需不需要写name
前端·vue.js
用户47949283569152 小时前
面试官:讲讲2FA 双因素认证原理
前端·后端·安全
乐影2 小时前
TS 模板字符串类型:从基础到进阶的类型编程魔法
前端·typescript
龙在天2 小时前
CSS 属性值的计算与过程
前端
云鹤_2 小时前
【Amis源码阅读】组件注册方法远比预想的多!
前端·低代码
子昕2 小时前
Claude Code插件系统上线!AI编程的“App Store”时代来了
ai编程
xinfei2 小时前
ES6 新特性 从 ECMAScript 2015(ES6)到 ECMAScript 2025
前端
GBVFtou3 小时前
vue响应式 track 和trigger 过程
前端
耀耀切克闹灬3 小时前
生成tag号的脚本
前端