Skip to content

实战案例:天气查询小工具完整开发实录

难度:⭐⭐ 进阶 | 工具:Codex / Claude Code | 耗时:约 30 分钟 | 技术栈:HTML + CSS + JS + API

项目背景

这是一个需要调用外部 API 的项目,比纯静态页面多了"数据获取"这一层。通过这个案例,你会学到怎么用提示词描述 API 调用、处理加载状态和错误处理。建议搭配 理解 AI 的输出:代码审查与调试 一起看。

前置准备:获取 API Key

我们使用 OpenWeatherMap 的免费 API:

  1. 打开 https://openweathermap.org/api
  2. 注册一个免费账号
  3. 在 Dashboard → API Keys 中复制你的 Key
  4. 免费额度:每分钟 60 次请求,完全够用

⚠️ 注意:注册后 API Key 可能需要等 10-30 分钟才能激活。

第一阶段:需求规划

MVP 功能

  • 输入城市名 → 显示当前温度和天气
  • 就这些,先让它能用

第二版

  • 加上湿度、风速等详细信息
  • 5 天天气预报
  • 背景颜色随天气变化

第三版

  • 搜索历史
  • 收藏城市
  • 定位功能

第二阶段:MVP 版本

提示词 #1:最简版本

text
帮我创建一个天气查询的网页应用。

这是 MVP 版本,只做最核心的功能:

【功能】
1. 页面中央有一个搜索框和搜索按钮
2. 输入城市名(支持中文和英文),按回车或点击按钮查询
3. 查询后在搜索框下方显示:
   - 城市名称
   - 当前温度(摄氏度,大字号显示)
   - 天气状况(用大号 emoji 表示,比如 ☀️🌤️⛅🌧️🌨️⛈️🌫️)
   - 一句天气描述文字(例如"多云")
4. 查询中显示 loading 状态
5. 城市不存在时显示友好的错误提示

【API 使用】
使用 OpenWeatherMap Current Weather API:
- 接口:https://api.openweathermap.org/data/2.5/weather
- 参数:q=城市名&units=metric&lang=zh_cn&appid=API_KEY
- API_KEY 用变量存储,放在 JS 最顶部,方便替换
- 返回数据中 main.temp 是温度,weather[0].description 是天气描述

【界面设计】
- 整体居中,最大宽度 480px
- 背景:渐变色 #667eea → #764ba2(蓝紫渐变)
- 搜索框和结果都放在一个白色半透明的毛玻璃卡片里:
  - 背景 rgba(255,255,255,0.15)
  - backdrop-filter: blur(20px)
  - 圆角 20px
- 搜索框:全宽,圆角,白色半透明背景,placeholder "输入城市名..."
- 温度数字:字号 80px,白色,加粗
- emoji:字号 60px
- 其他文字:白色,14-16px

【技术要求】
- 纯 HTML + CSS + JavaScript,单文件
- 使用 fetch API 发请求
- 请求出错时 catch 并显示错误信息

请生成完整代码。API_KEY 部分用 'YOUR_API_KEY_HERE' 占位。

效果检查

检查项结果备注
页面打开
搜索"北京"正常显示温度
搜索"abc123"显示"城市未找到"
Loading 状态有旋转动画
手机端⚠️搜索框有点挤
Emoji 显示⚠️天气代码到 emoji 的映射不全

提示词 #2:修复 emoji 映射 + 手机端

text
两个问题需要修复:

1. 天气图标的 emoji 映射不够全面。请按照 OpenWeatherMap 的天气代码完善:
   - 200-299(雷暴):⛈️
   - 300-399(毛毛雨):🌦️
   - 500-504(雨):🌧️
   - 511(冻雨):🌨️
   - 520-531(阵雨):🌧️
   - 600-699(雪):🌨️
   - 700-799(雾/霾):🌫️
   - 800(晴):根据 icon 字段判断白天 ☀️ / 夜晚 🌙
   - 801(少云):🌤️
   - 802(多云):⛅
   - 803-804(阴天):☁️

   天气代码从 API 返回的 weather[0].id 获取。

2. 手机端搜索框和按钮的布局需要优化:
   - 搜索框和按钮改成上下排列(搜索框全宽,按钮全宽在下面)
   - 或者让搜索框占大部分宽度,按钮缩小为一个搜索图标
   - 卡片的左右 padding 在手机端改为 20px

其他不变。

第三阶段:丰富信息展示

提示词 #3:添加详细天气信息

text
在当前基础上,丰富天气信息展示:

1. 在温度和 emoji 下方,添加一行详细信息网格(2x2 布局):
   - 体感温度:main.feels_like + "°C",前面放 🌡️ 图标
   - 湿度:main.humidity + "%",前面放 💧 图标
   - 风速:wind.speed + " m/s",前面放 🌬️ 图标
   - 气压:main.pressure + " hPa",前面放 📊 图标

   每个信息项包含:图标 + 数值 + 标签(灰色小字)
   网格间距 12px,每个项目有半透明背景卡片

2. 在详细信息下方,显示日出和日落时间:
   - 从 sys.sunrise 和 sys.sunset 获取(Unix 时间戳,需要转换)
   - 格式:🌅 06:23  🌇 18:45
   - 水平排列,居中

3. 背景渐变色根据天气变化(CSS transition 0.8s 平滑过渡):
   - 晴天白天:#2196F3 → #64B5F6(亮蓝)
   - 晴天夜晚:#1a1a3e → #2d2d6e(深蓝紫)
   - 多云:#78909C → #B0BEC5(灰蓝)
   - 雨天:#37474F → #546E7A(深灰)
   - 雪天:#B3E5FC → #E1F5FE(淡蓝白)
   - 判断白天/夜晚:用 icon 字段,以 'd' 结尾是白天,'n' 结尾是夜晚

所有新增内容都要有淡入动画(opacity 0 → 1,0.5s)。
其他已有功能不要改动。

踩坑记录

这轮遇到了一个问题:日出日落时间显示的是 UTC 时间,不是当地时间

我的修复提示:

text
日出日落时间显示不对。现在显示的是 UTC 时间,但应该显示查询城市的当地时间。

API 返回的 timezone 字段是该城市相对 UTC 的秒数偏移。
请用这个公式计算当地时间:
localTime = new Date((timestamp + timezone) * 1000)

然后用 getUTCHours() 和 getUTCMinutes() 来格式化,
不要用 getHours()(那是浏览器本地时区)。

💡 踩坑经验:时区问题是 API 项目中最常见的坑之一。当你发现时间"不太对"的时候,十有八九是时区问题。把你的预期计算方式告诉 AI 比说"时间不对"有效得多。

第四阶段:5 天预报

提示词 #4:添加预报

text
添加未来 5 天的天气预报:

1. API 调用:
   - 使用 5 Day Forecast API:https://api.openweathermap.org/data/2.5/forecast
   - 参数和当前天气 API 一样
   - 这个 API 返回每 3 小时的预报,我们需要把它按天分组
   - 每天取中午 12:00 的数据作为当天代表(如果没有12点的,取最接近的)

2. 展示方式:
   - 在详细信息下方,水平排列 5 个小卡片
   - 每个卡片包含:星期几(如"周一")、天气 emoji、最高温/最低温
   - 最高温和最低温分别用红色和蓝色文字
   - 卡片可以水平滚动(如果手机端放不下的话)
   
3. 样式:
   - 每个卡片 80px 宽,半透明白色背景
   - 卡片之间间距 8px
   - 星期几的文字 12px,温度 16px,emoji 30px

4. 数据处理:
   - 星期几用中文显示(周一、周二...)
   - 温度四舍五入到整数
   - 如果是今天,显示"今天"而不是星期几

两个 API 请求(当前天气 + 预报)用 Promise.all 并行发送,提高速度。
保持已有功能不变。

第五阶段:搜索历史 + 收藏

提示词 #5:用户体验优化

text
最后一轮优化,添加搜索历史和收藏功能:

1. 搜索历史:
   - 每次成功查询后,把城市名存到 localStorage
   - 最多保存 5 条历史记录(新的在前面,超过5条删除最早的)
   - 在搜索框下方显示历史记录标签(小圆角胶囊)
   - 点击标签直接搜索该城市
   - 每个标签右上角有 × 可以单独删除

2. 收藏城市:
   - 在当前天气卡片右上角加一个 ⭐ 收藏按钮
   - 点击后变成实心星(已收藏),再点取消
   - 收藏列表存 localStorage,在页面顶部显示(如果有的话)
   - 收藏的城市用圆角标签展示,带城市名和当前温度
   - 页面加载时自动获取所有收藏城市的温度

3. 刷新按钮:
   - 在天气信息右上角加一个🔄刷新按钮
   - 点击重新获取当前城市的天气数据
   - 按钮点击时有旋转动画

所有数据保存在 localStorage 中。保持已有功能不变。

开发总结

时间花费

阶段耗时说明
获取 API Key3 分钟注册 + 等激活
需求规划2 分钟
MVP 版本5 分钟
修复 + 信息丰富10 分钟3 轮迭代
5 天预报5 分钟
搜索历史 + 收藏5 分钟
总计~30 分钟

关键经验

  1. API 类项目要先测通接口:先用最简单的方式确认 API 能调通,再加界面
  2. 错误处理很重要:网络请求可能失败,用户可能输入乱七八糟的东西
  3. 时区是个坑:涉及时间的项目一定要注意时区转换
  4. 并行请求优化体验:多个 API 调用用 Promise.all
  5. 给出完整的 API 细节:告诉 AI 具体的接口地址、参数名、返回字段,减少猜测

踩坑汇总

问题原因解决方式
emoji 映射不全AI 只覆盖了常见天气给出完整的天气代码对照表
日出日落时间不对UTC 时间没转当地时区用 timezone 偏移量手动计算
5 天预报数据重复API 返回每 3 小时数据明确说要按天分组 + 取中午数据
收藏城市加载慢串行请求改用 Promise.all 并行

给你的挑战

  1. 添加地理定位:用浏览器 Geolocation API 自动获取当前位置
  2. 添加天气动画:晴天显示太阳动画,雨天显示雨滴动画
  3. 添加穿衣建议:根据温度自动推荐
  4. PWA 改造:可以添加到手机桌面,离线显示上次的数据

继续阅读

基于新版 vibe-coding 教程全集整理