Appearance
实战案例:天气查询小工具完整开发实录
难度:⭐⭐ 进阶 | 工具:Codex / Claude Code | 耗时:约 30 分钟 | 技术栈:HTML + CSS + JS + API
项目背景
这是一个需要调用外部 API 的项目,比纯静态页面多了"数据获取"这一层。通过这个案例,你会学到怎么用提示词描述 API 调用、处理加载状态和错误处理。建议搭配 理解 AI 的输出:代码审查与调试 一起看。
前置准备:获取 API Key
我们使用 OpenWeatherMap 的免费 API:
- 打开 https://openweathermap.org/api
- 注册一个免费账号
- 在 Dashboard → API Keys 中复制你的 Key
- 免费额度:每分钟 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 Key | 3 分钟 | 注册 + 等激活 |
| 需求规划 | 2 分钟 | |
| MVP 版本 | 5 分钟 | |
| 修复 + 信息丰富 | 10 分钟 | 3 轮迭代 |
| 5 天预报 | 5 分钟 | |
| 搜索历史 + 收藏 | 5 分钟 | |
| 总计 | ~30 分钟 |
关键经验
- API 类项目要先测通接口:先用最简单的方式确认 API 能调通,再加界面
- 错误处理很重要:网络请求可能失败,用户可能输入乱七八糟的东西
- 时区是个坑:涉及时间的项目一定要注意时区转换
- 并行请求优化体验:多个 API 调用用 Promise.all
- 给出完整的 API 细节:告诉 AI 具体的接口地址、参数名、返回字段,减少猜测
踩坑汇总
| 问题 | 原因 | 解决方式 |
|---|---|---|
| emoji 映射不全 | AI 只覆盖了常见天气 | 给出完整的天气代码对照表 |
| 日出日落时间不对 | UTC 时间没转当地时区 | 用 timezone 偏移量手动计算 |
| 5 天预报数据重复 | API 返回每 3 小时数据 | 明确说要按天分组 + 取中午数据 |
| 收藏城市加载慢 | 串行请求 | 改用 Promise.all 并行 |
给你的挑战
- 添加地理定位:用浏览器 Geolocation API 自动获取当前位置
- 添加天气动画:晴天显示太阳动画,雨天显示雨滴动画
- 添加穿衣建议:根据温度自动推荐
- PWA 改造:可以添加到手机桌面,离线显示上次的数据
