
简介一份面向计算机、电子信息工程等专业毕业生的城市天气小程序源码属于高分毕设项目可同时用于课程设计与期末大作业。源码采用Java作为后端支撑前端为微信小程序结构压缩包内共23个文件核心类型包括.js逻辑脚本、.wxml页面结构、.wxss样式、.json配置及.less样式预处理文件目录涵盖pages页面、utils工具模块与libs第三方库如bluebird、crypto-js、uuid可清晰还原项目分层与请求加密流程。资源包整体仅345KB结构紧凑、调试完整代码经过严格验证无Bug。当前已有97人浏览学习特别适合需要快速搭建天气类小程序项目、理解小程序前后端协作及掌握毕设代码规范的读者。通过阅读源码可学习到天气数据解析、工具函数封装、全局配置管理及组件化页面设计等关键实践为独立完成毕业设计或求职作品集提供直接参考。1. 城市天气小程序源码毕业设计从哪一步开始读从网盘里下到这样一个 zip 包名字里带着“高分项目”“优秀毕业设计”大多数人的第一动作是解压、拖进微信开发者工具然后看着报错提示发愣。城市天气小程序是一个典型的微信小程序完整项目页面、接口请求、城市管理、天气展示都塞在同一个工程里难度不高但链路齐全这也是它成为毕业设计高频选题的原因。对初学小程序的人来说它比商城、外卖这类项目更容易读完整也更容易在答辩时把每一块功能讲清楚。拿到源码先别急着删掉重写。先确认三件事小程序 AppID 有没有替换、天气接口的密钥写在哪、请求域名是否在白名单里。这三项对上之后项目通常几分钟内能跑起来之后再谈读代码和二次开发。下面按这个顺序把城市天气小程序源码里的关键位置逐层拆开从目录结构讲到接口封装再讲到上线前必改的配置。整个过程不需要后端服务器适合个人开发者在本地直接复现。2. 拆解城市天气小程序的源码结构与技术选择2.1 微信小程序原生开发的目录约定城市天气小程序大多数基于微信小程序原生语法编写目录结构比较统一。拿到 zip 解压后先看根目录通常会有 app.js、app.json、app.wxss 和 pages、utils、components 这些目录。app.json 是全局配置页面路由、窗口样式、tabBar 都在这里定义app.js 里存放全局生命周期和公共数据。这套结构既是微信小程序的规范也是答辩评审一定会看的部分所以原封不动保留它是值得的。需要说明的是目录组织在不同源码里会有差异。如果 zip 里出现 src/pages 和 manifest.json说明这是 uni-app 版本不能直接导入微信开发者工具要先通过 HBuilderX 发行或 CLI 编译成微信小程序。很多学生下载时没注意这个区别导致按原生项目流程操作半天仍然无法编译。这个判断要在解压后立刻做避免在环境问题上浪费一整天。下面是一份常见目录职责对照表具体路径以你手上的源码为准。路径职责二次开发时改动点app.json页面路由、全局窗口、权限声明新增页面时要补路径pages/index/天气主页面展示实时天气数据绑定、接口调用pages/city/城市选择页或城市管理城市列表、搜索逻辑utils/request.jswx.request 的 Promise 封装补全 API Key、超时处理components/自定义组件如天气图标一般无需改动images/图标、背景图按需要替换这份表里最值得关注的是 utils/request.js。很多毕业设计源码把接口请求直接写在页面里而优秀项目会单独抽一层 request因为后续加接口、统一处理错误会更加方便。城市天气场景下至少有两个接口实时天气和城市搜索如果每个页面都写一遍 wx.request代码量会翻倍答辩时也难以自圆其说。如果源码里没有 utils 目录建议自己补一个把网络请求从页面中拆出来这本身就是一次有价值的代码重构。2.2 app.json 里藏着天气小程序的全局策略先看 app.json不要急着打开页面代码。城市天气小程序最少需要两个页面首页和城市选择页。首页负责展示天气城市页负责返回选择结果。窗口配置里会设置 navigationBarTitleText 为“城市天气”背景色一般配合天气主题做蓝色或渐变处理。下面是一段典型的 app.json 配置{ pages: [ pages/index/index, pages/city/city ], window: { navigationBarTitleText: 城市天气, navigationBarBackgroundColor: #4A90D9, navigationBarTextStyle: white }, permission: { scope.userLocation: { desc: 用于获取当前位置的天气信息 } } }这段配置有三个要点。pages 数组第一项是启动页城市天气项目里通常是首页不要随意调整顺序否则编译后打开的是另一页navigationBarTitleText 决定顶部标题文字后面可以用 wx.setNavigationBarTitle 动态修改这也是微信小程序动态设置标题的标准做法permission 里的 scope.userLocation 是定位权限声明没有这段配置调用 wx.getLocation 时授权弹窗会显示默认文案审核时可能因为用途不明被驳回。用户隐私保护新规之后这里要和 mp 后台填写的隐私指引保持一致。从请求链条看数据流可以概括为页面 onLoad 触发请求请求模块携带 location 和 key 调用天气 API拿到 results 后 setData页面重新渲染。原生开发中页面负责传参utils 负责网络组件负责展示职责边界比看起来清晰得多。如果源码里用了全局变量存城市名则要额外关注 getApp().globalData 的更新时机避免切换城市后页面读取到旧值。2.3 为什么城市天气这个题目能拿高分城市天气适合做毕业设计不是因为简单而是因为它每一步改动都能对应到具体技术点。城市从写死改成可搜索是数据结构与列表渲染的配合单日天气改成未来五天预报是数组循环和样式复用文字天气说明改成图标组件是自定义组件的拆分。这些改动在答辩时都能讲出实现思路而不是空口说“我做了个网页”。另一个原因是演示场景完整。打开小程序授权定位自动获取所在城市天气手动切换城市界面立即刷新下拉刷新重新请求。用户每一步操作都有反馈评委不需要懂代码也能看到功能闭环。对初学微信小程序的人来说这份源码是很好的脚手架但不要原封不动交上去至少要换掉默认配色和图标再做一个小功能差异。比如增加“上次更新时间”字段或者加入天气预警提醒都能成为项目文档里的亮点。3. 天气接口接入与城市选择的代码实现3.1 免费天气 API 的选型看 key、看单位、看限流城市天气小程序源码里天气数据通常来自第三方开放 API。常见的有心知天气、和风天气、高德天气。它们都提供免费层级但免费额度、更新频率和返回字段差异明显。毕业设计场景下选择标准不是“哪个准”而是“哪个文档最容易读懂、返回值最直观”。如果源码里已经写了某个 API尽量沿用同一个换接口的成本不只是改 URL字段映射也要全部调整。API免费额度单位参数常见字段心知天气每日一定次数调用unitc/fresults[0].now和风天气按日请求量限制unitm公制now.temp高德天气每日限流extensionsbase/alllives[0].temperature大多数城市天气源码选用心知天气因为返回结构简单location 可以直接传城市中文名适合学生项目。高德天气更适合已经有高德地图定位的项目返回字段用 lives 包裹初次看会不习惯。无论用哪家替换 key 后都要先确认单位参数。常见问题是源码里写 unitc但文档默认返回华氏度导致页面温度数值看起来差别很大。换接口前先在浏览器里访问一次 API URL确认返回 JSON 结构再改代码里的字段映射这一步能省下大量排错时间。API Key 是敏感信息很多源码把 key 写在 config.js 里只做本地调试没问题但提交代码时注意不要把 key 推到公开仓库。免费接口的 key 通常有每日调用次数限制毕业设计展示时连续反复进入页面可能触发限流。为了避免这种情况后面会讲一个缓存方案用 Storage 减少重复请求。3.2 用 Promise 封装 wx.request避免回调地狱优秀城市天气源码一定会在 utils 里封装请求。原因很简单天气接口最少有两类请求实时天气和城市搜索如果不统一封装每个页面都要处理 statusCode 和错误提示代码会大量重复。下面的封装可以直接抄到你的项目里// utils/request.js const CONFIG require(../config.js); function request(path, data {}) { return new Promise((resolve, reject) { wx.request({ url: CONFIG.BASE_URL path, data: { key: CONFIG.WEATHER_KEY, unit: c, ...data }, timeout: 5000, success(res) { if (res.statusCode 200) { resolve(res.data); } else if (res.statusCode 401 || res.statusCode 403) { wx.showToast({ title: API Key 无效, icon: none }); reject(res); } else { wx.showToast({ title: 天气服务异常, icon: none }); reject(res); } }, fail(err) { wx.showToast({ title: 网络请求失败, icon: none }); reject(err); } }); }); } module.exports { request };这里有几个参数需要说明。timeout 设成 5000避免弱网环境下页面长时间 loadingunit: c 是心知天气的摄氏度参数不同 API 的单位参数不一样换成和风天气时要去掉这一项key 在每次请求里以参数携带比在 URL 里硬拼更直观。success 回调里按 statusCode 分流401 和 403 都是密钥问题提示文案要明确否则用户在真机上看到一片空白不知道原因。fail 分支覆盖两类情况一是网络断开二是域名没有配置到白名单。真机上如果频繁提示网络请求失败第一反应不是改代码而是去小程序后台检查 request 合法域名。另外如果源码里已经使用了 async/await调用 request 时前面要写 await并且外层函数需要声明 async否则返回值变成 Promise 对象页面拿不到实际数据。这个细节在答辩代码评审时经常被问到。3.3 城市选择用 picker 还是独立城市页城市天气源码里选择城市有两种实现。轻量版用 picker 组件在首页底部弹出滚动选择器完整版单独建一个 city 页面带搜索和热门城市。毕业设计如果想体现工作量独立城市页更合适如果只是把功能跑通picker 足够了。城市页的核心是列表渲染和事件回传picker 的核心是 index 绑定两者都不难但有一个容易踩的坑。picker 的写法如下// pages/index/index.js const CITIES [北京, 上海, 广州, 深圳, 杭州, 成都]; Page({ data: { cities: CITIES, cityIndex: 0, activeCity: 北京 }, onCityChange(e) { const index Number(e.detail.value); const city CITIES[index]; this.setData({ cityIndex: index, activeCity: city }); wx.setStorageSync(lastCity, city); this.fetchWeather(city); } });e.detail.value 从 picker 返回的是字符串比如字符串 “2”直接拿去做数组下标会得到 undefined因为数组下标只能是 number。这里先用 Number 转成数字这一行是城市选择功能最容易漏掉的细节。storage 用固定 key lastCity 保存当前选择下次启动时在 onLoad 里读取就能恢复用户上次看的城市。注意 setStorageSync 是同步写操作城市切换时调用不会阻塞 UI数据量小适合这种场景。如果城市列表和天气 API 的 location 参数不是同一个值还需要一层映射。例如列表显示“北京”接口需要 beijing用一个 cityMap 对象做转换。源码中的常见做法是 CITIES 数组只存中文名fetchWeather 里查 cityMap 得到拼音参数字段这样展示层和接口层解耦。如果接口支持中文名可以省掉这层映射但要注意 URL 编码中文必须经过 encodeURIComponent 转义。3.4 定位授权避免启动时白屏的关键逻辑城市天气小程序通常会支持自动定位。实现方式是 wx.getLocation 获得经纬度再把经纬度传给天气 API。心知天气和和风天气都支持 location 直接传“经度,纬度”格式所以不需要额外接逆地理编码接口。这个设计让源码少一个第三方依赖也减少了答辩时的外部因素。下面是一段定位回退逻辑onLoad() { const last wx.getStorageSync(lastCity); if (last) { this.setData({ activeCity: last }); } wx.getLocation({ type: gcj02, success: (res) { this.fetchWeather(${res.longitude},${res.latitude}); }, fail: () { this.fetchWeather(this.data.activeCity); } }); }成功回调里没有再次 setData 城市名因为经纬度反查城市名需要逆地理编码接口这里只更新天气数据。fail 分支处理用户拒绝授权的情况此时回退到上次保存的城市如果连 lastCity 也没有页面应显示默认城市和重新选择的按钮而不是一直转圈。定位授权弹窗在模拟器里可以直接勾选在真机上第一次弹窗时如果误点拒绝需要在设置页引导用户打开授权这是天气小程序答辩时被问到的常见问题。如果源码里缺少这个回退逻辑建议自己补上能明显提升项目的健壮性。4. 把源码跑起来导入、配置和真机预览4.1 解压 zip 后不要直接拖压缩包进开发者工具下载的 zip 包第一件事是解压到英文路径的目录。微信开发者工具不能直接导入压缩包解压后的目录名里如果有中文或空格部分 Windows 环境会导致路径解析异常报“文件不存在”。建议重命名为 weather-miniprogram 这样的名字再打开微信开发者工具选择“导入项目”目录指向解压后的根目录。导入时工具会读取 project.config.json如果这个文件缺失会当作无项目配置的空目录处理。原生微信小程序源码一般没有 node_modules也不需要 npm install。这一点和常见的开源 JS 项目不同。只有出现 package.json 且引用了 npm 包时才需要在工具里执行“工具-构建 npm”。如果解压后看到大量 node_modules 文件反而说明项目可能混入了无关文件直接删掉再导入减小体积。导入后如果工程名是英文、图标是默认图先不要着急改先把编译跑通再换图标和标题。4.2 必改的 4 个配置项城市天气源码大概率使用原作者的个人 AppID 和自己的天气 API Key。发布前必须替换否则真机上会显示开发版不受信任或者接口返回 401。按改动位置整理成一张表配置项位置改法不改的后果AppIDproject.config.json换成你自己的 appid预览二维码无法加载API Keyconfig.js替换 WEATHER_KEY接口返回 401合法域名mp 后台 开发管理添加天气 API 域名真机请求被拦截开发时域名校验开发者工具详情 本地设置开发阶段勾选“不校验合法域名”模拟器请求也失败project.config.json 里的 appid 字段在导入时如果选择“测试号”工具会自动生成一个临时 AppID但真机预览时很多功能受限。正式调试建议注册一个小程序账号拿到自己的 AppID。不要在一开始就把项目里的 AppID 删成空字符串游客模式虽然进入项目更顺利但 wx.request 和 wx.getLocation 的部分行为会被限制导致天气请求能发出定位却一直在 fail排错成本更高。合法域名是另一个高发问题。模拟器里勾选“不校验合法域名”后请求能通但真机预览仍然会拦截。此时必须把天气 API 的域名加到小程序后台的 request 合法域名列表且必须是 HTTPS不支持 IP 和端口。如果使用 http:// 开头的接口地址即使加了白名单也无法访问因为微信要求所有网络请求必须走 HTTPS。这个限制在开发版和体验版都生效和是否发布无关。4.3 用 Network 面板定位接口问题跑通首次请求后不要只盯着页面。微信开发者工具左上角的调试器里Network 面板会列出所有网络请求。点击天气接口那条记录能看到完整请求 URL、Query String、响应体这是排查“页面空白”最快的路径。下面是一张状态码速查表现象状态码处理方向接口返回 200 但页面无数据200字段名没对上检查 results[0].now 层级API Key 无效401替换 config.js 里的 key真机请求失败fail检查合法域名和 HTTPS返回 404404URL 路径或版本号错误如果 200 还没数据把响应 JSON 贴在代码里对比字段名。心知天气返回结果是 results[0].now.text和风天气是 now.text层级不同。直接把源码里的字段名改成接口实际返回的字段即可。这个坑在天气小程序源码里出现频率极高原因是原作者用的接口和后来下载者换的接口不是同一个。Network 面板里还能看到请求耗时如果天气接口耗时稳定在 1 秒以上需要考虑加缓存或换免费 API 节点这是后文优化的方向。5. 从毕业设计到可上线的天气小程序缓存与动态标题5.1 用 Storage 做 10 分钟天气缓存天气数据不需要每次进入都重新请求。给接口加一个本地缓存既减少 API 消耗又提升页面速度。城市天气小程序里适合用城市名作为 key 的一部分同一个 key 存不同城市会互相覆盖。下面是一个简单的缓存封装const CACHE_PREFIX weather_; const EXPIRE_TIME 10 * 60 * 1000; function getWeatherWithCache(city) { const cacheKey CACHE_PREFIX city; const cached wx.getStorageSync(cacheKey); if (cached Date.now() - cached.time EXPIRE_TIME) { return Promise.resolve(cached.data); } return request(/weather/now, { location: city }).then(data { wx.setStorageSync(cacheKey, { time: Date.now(), data }); return data; }); }缓存失效时间 10 分钟单位毫秒time 保存的是请求完成的时间不是页面打开时间缓存的 data 只存接口返回体不存整个 res避免把无关字段写进本地。下拉刷新时应该绕过缓存直接调 request再更新缓存。这个封装里有个细节返回 Promise.resolve(cached.data)调用方原有的 then 逻辑不用改动缓存和网络请求对页面而言是透明的。5.2 切换城市时用 setNavigationBarTitle 让标题跟着变城市切换后顶部标题还显示“城市天气”会显得页面没有联动。微信小程序提供了动态设置标题的接口一个提升观感的细节实现this.setData({ activeCity: city }); wx.setNavigationBarTitle({ title: city 天气 });这段代码放在城市选择的回调里和 storage 写入放在一起。真机上标题会立即变化不需要重新编译。如果页面还有下拉刷新刷新后也要重新设置一次标题因为 onShow 时标题可能被全局配置重置。这个技巧同样适用于需要展示当前上下文的其他小程序页面结合导航栏高度适配可以让天气页在不同机型上顶部表现一致。5.3 上线前检查三项配置发布前把开发者工具里的“不校验合法域名”取消勾选再跑一遍所有页面。同时确认小程序后台已经添加天气 API 的合法域名域名证书在有效期内。最后在 mp 后台填写用户隐私保护指引因为调用了 wx.getLocation必须声明定位用途否则审核阶段会被驳回。这三项做完城市天气小程序就可以上传体验版进入真机测试和提审流程。本文还有配套的精品资源点击获取