课程 | 中国海洋大学22夏《移动软件开发》 |
实验名称 | 实验2:天气查询小程序 |
一、实验目标
1、掌握服务器域名配置和临时服务器部署;
2、掌握 wx.request 接口的用法。
二、实验步骤
1. 准备工作
-
API 密钥申请
选择可提供全球气象数据服务接口的 和风天气API ;
官方网址: https://www.qweather.com
此处选择 天气API 进行注册。
由网址 控制台 | 和风天气 (qweather.com) 进入控制台查看账号信息。
在左侧栏选择 应用管理。
选择免费开发版。
填写应用名称。
选择 Web API
填写 KEY 的名称
点击 创建 即可获取 KEY 。
-
微信小程序后台域名配置
-
由以下网址进入和风天气开发平台获取开发版 API 。
https://dev.qweather.com/docs/api/weather/weather-now/
-
登陆微信公众平台的小程序后台,进入 开发 -> 开发管理 -> 开发设置 下的服务器域名。
将我们要用到的 API 的域名
https://devapi.qweather.com
添加到request合法域名里面。
保存后可以看到修改结果。
-
-
素材下载 实验中需要的天气图片、utils.js下载地址为:
https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/demo2_file.zip
2. 创建项目
项目名称与目录为默认;
AppID点击右侧三角后即可选择;
后端服务选择不适用云服务;
模板选择官方的JavaScript。
3. 页面配置
-
新建项目
-
创建页面文件 并 删除和修改文件
-
[删除] utils文件夹及其内部所有内容;
-
[删除] app.json 文件内 pages 属性中的 "pages/logs/logs",并[删除] pages 文件夹下的 logs 目录机器内部所有内容;
-
[删除] index.wxml 及 index.wxss 文件中全部的代码;
-
[删除] index.js 中的全部代码,并输入关键词 page 找到并补全函数。
-
[删除] app.wxss 文件中全部的代码;
-
[删除] app.js 中的全部代码,并输入关键词 app 找到并补全函数。
-
创建图表文件夹
-
在中间的目录结构单击 右键 新建 images 文件夹。
右键单击 image 文件夹,点击 [在资源管理器中打开] 。将下载好的天气图片放入此文件夹。
-
将下载的 utils 文件夹放入 index 目录下。
-
4. 视图设计
-
导航栏
修改 app.json 中的 windows 属性代码为:
{ "pages": [ "pages/index/index" ], "window": { "navigationBarBackgroundColor": "#003153", "navigationBarTitleText": "今 日 天 气", "navigationBarTextStyle": "white" }, "sitemapLocation": "sitemap.json" }
字体颜色:普鲁士蓝 ;导航栏标题:今 日 天 气;导航栏字体颜色:白色。
-
页面设计
页面上主要包含四个区域:
-
区域 1:地区选择器,用户可以自行选择查询的省、市、区; picker 组件;
-
区域 2:显示当前城市的温度和天气状态的文字说明; text 组件;
-
区域 3:显示当前城市的天气图标; image 组件;
-
区域 4:分多行显示其他天气信息,例如湿度、气压、能见度和风向等;
view 组件,并定义 class='detail';
区域4内单元行:4个 view 组件,并定义class='bar';
区城4内单元格:每行3个 view 组件,并定义class='box'。
-
页面整体:view 组件,并定义 class= 'container';
-
整体容器设计
-
定义页面容器 ( view 组件)
-
index.wxml 代码:
<!--index.wxml--> <view class="container"> </view>
app.wxss 代码:
/*页面容器样式*/ .container{ height: 100vh; /*高度100视窗*/ display: flex; /*flex布局*/ flex-direction: column; /*垂直布局*/ align-items: center; /*水平居中*/ justify-content: space-around; /*垂直方向分散分布*/ }
-
-
地区选择器设计
使用 picker 组件实现。
index.wxml 代码:
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> <picker mode="region"> <view>北京市</view> </picker> </view>
picker 组件内部填写任意一个城市,点击此城市名后下方弹出选择控制台。
-
文本设计
index.wxml 内添加代码:
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> …… <!--区域 2:文本设计--> <text>19°C 晴</text> </view>
index.wxss 添加文本样式代码:
/*文本样式*/ text{ font-size: 80rpx; color:#081746; }
-
天气图标设计
index.wxml 内添加代码:
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> …… <!--区域 2:文本设计--> …… <!--区域 3:天气图标设计--> <image src="/images/weather_icon_s1_color/999.png"></image> </view>
第 999 号为 N/A ,即未知天气。
index.wxss 添加文本样式代码:
/*天气图标样式*/ image{ width: 220rpx; }
-
多行天气信息设计
使用 view 组件。
index.wxml 内添加代码:
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> …… <!--区域 2:文本设计--> …… <!--区域 3:天气图标设计--> …… <!--区域 4:多行天气信息设计--> <view class='detail'> <view class='bar'> <view class='box'>湿度</view> <view class='box'>气压</view> <view class='box'>能见度</view> </view> <view class='bar'> <view class='box'>0 %</view> <view class='box'>0 hPa</view> <view class='box'>0 km</view> </view> <view class='bar'> <view class='box'>风向</view> <view class='box'>风速</view> <view class='box'>风力</view> </view> <view class='bar'> <view class='box'>0</view> <view class='box'>0 km/h</view> <view class='box'>0 级</view> </view> </view> </view>
index.wxss 添加文本样式代码:
/*区域 4 整体样式*/ .detail{ width: 100%; display: flex; flex-direction: column; } /*区域 4 单元行样式*/ .bar{ display: flex; flex-direction: row; margin: 35rpx 0; /*外边距*/ } /*区域 4 单元格样式*/ .box{ width: 33.3%; text-align: center; }
-
5. 逻辑实现
-
更新省、市、区信息
修改 index.wxml 的 picker 组件中的 北京市 为 {{region}},追加 bindchange 用于监听选项变化。
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> <picker mode="region" bindchange="regionChange"> <view>{{region}}</view> </picker> </view>
地区选择器返回结果为数组,index.js 文件中的 data 属性下定义 region 为包含省、市、区信息的数组。
自定义初始信息。
//index.js const util = require('/utils/util.js'); Page({ /** * 页面的初始数据 */ data: { region: ['北京市', '北京市', '海淀区'], }, /* 更新省、市、区信息*/ regionChange: function(e) { this.setData({ region: e.detail.value }); } })
-
获取实况天气数据
在 index.js 文件的 Page 函数中自定义 getWeather 函数。
/*获取实况天气数据*/ getWeather: function () { var that = this; wx.request({ url: 'https://devapi.qweather.com/v7/weather/now', data:{ location: util.getLocationID(that.data.region[1]), key: '467b09ceb85c479a9a2384675039ad4c' }, success:function(res){ that.setData({now:res.data.now}); } }) },
将 getWeather 函数在自定义函数 regionChange 与函数 onLoad 中分别调用。
实况天气信息包含在 now 中;更新 getWeather 函数。
/* 更新省、市、区信息*/ regionChange: function(e) { this.setData({ region: e.detail.value }); this.getWeather(); }, /*获取实况天气数据*/ getWeather: function () { var that = this; wx.request({ url: 'https://devapi.qweather.com/v7/weather/now', data:{ location: util.getLocationID(that.data.region[1]), key: '467b09ceb85c479a9a2384675039ad4c' }, success:function(res){ that.setData({now:res.data.now}); } }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { this.getWeather(); }
-
更新页面天气信息
由网址
https://devapi.qweather.com/v7/weather/now?location=101010100&key='你的KEY'
获取天气信息。
所得内容经整理,可以得到 now 的参数。
{"code":"200", "updateTime":"2022-08-17T22:07+08:00", "fxLink":"http://hfx.link/2ax1", "now":{"obsTime":"2022-08-17T21:54+08:00", "temp":"28", "feelsLike":"29", "icon":"151", "text":"多云", "wind360":"180", "windDir":"南风", "windScale":"1", "windSpeed":"5", "humidity":"71", "precip":"0.0", "pressure":"1001", "vis":"16", "cloud":"91", "dew":"23"}, "refer":{ "sources":["QWeather","NMC","ECMWF"], "license":["no commercial use"] } }
在 index.js 的 data 属性中给 now 规定初始数据。
/** * 页面的初始数据 */ data: { region: ['北京市', '北京市', '海淀区'], now:{ temp: 0, //温度 text: '未知', //天气 icon: '999', //天气编号 humidity: 0, //湿度 pressure: 0, //气压 vis: 0, //能见度 windDir: 0, //风向 windSpeed: 0, //风速 windScale: 0 //风力 } },
实现页面更新天气信息。
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> …… <!--区域 2:文本设计--> …… <!--区域 3:天气图标设计--> …… <!--区域 4:多行天气信息设计--> <view class='detail'> <view class='bar'> <view class='box'>湿度</view> <view class='box'>气压</view> <view class='box'>能见度</view> </view> <view class='bar'> <view class='box'>{{now.humidity}} %</view> <view class='box'>{{now.pressure}} hPa</view> <view class='box'>{{now.vis}} km</view> </view> <view class='bar'> <view class='box'>风向</view> <view class='box'>风速</view> <view class='box'>风力</view> </view> <view class='bar'> <view class='box'>{{now.windDir}}</view> <view class='box'>{{now.windSpeed}} km/h</view> <view class='box'>{{now.windScale}} 级</view> </view> </view> </view>
三、问题总结与体会
1. 遇到的问题及解决方法
-
API 调用出错
使用下载好的 utils 文件夹中的文件。
在 index.js 中加入如下语句。
//index.js const util = require('/utils/util.js');
-
无法获取天气信息
教程中的参数与目前版本使用的参数有所不同。
从开发平台拿到 API 后获取天气信息,即可活得天气相关参数。
-
位置无法获取
HeWeather[0].now 属性目前版本已无法使用。
相关语句修改为
location: util.getLocationID(that.data.region[1]),
that.setData({now:res.data.now});
-
多云天气无法显示图表
多云天气图标编号为 151;下载的多云图片编号为 153。修改文件名即可。
2. 总结与体会
-
熟悉并学习使用免费的 API,十分方便。
-
小程序开发环境更新换代十分迅速。大部分时间花在了找新版本的 API 和天气参数上。
四、完整代码
index.js
//index.js const util = require('/utils/util.js'); Page({ /** * 页面的初始数据 */ data: { region: ['北京市', '北京市', '海淀区'], now:{ temp: 0, //温度 text: '未知', //天气 icon: '999', //天气编号 humidity: 0, //湿度 pressure: 0, //气压 vis: 0, //能见度 windDir: 0, //风向 windSpeed: 0, //风速 windScale: 0 //风力 } }, /* 更新省、市、区信息*/ regionChange: function(e) { this.setData({ region: e.detail.value }); this.getWeather(); }, /*获取实况天气数据*/ getWeather: function () { var that = this; wx.request({ url: 'https://devapi.qweather.com/v7/weather/now', data:{ location: util.getLocationID(that.data.region[1]), key: '467b09ceb85c479a9a2384675039ad4c' }, success:function(res){ that.setData({now:res.data.now}); } }) }, /** * 生命周期函数--监听页面加载 */ onLoad: function(options) { this.getWeather(); }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { this.getWeather(); } })
index.wxml
<!--index.wxml--> <view class="container"> <!--区域 1:地区选择器--> <picker mode="region" bindchange="regionChange"> <view>{{region}}</view> </picker> <!--区域 2:文本设计--> <text>{{now.temp}}°C {{now.text}}</text> <!--区域 3:天气图标设计--> <image src="/images/weather_icon_s1_color/{{now.icon}}.png" mode='widthFix'></image> <!--区域 4:多行天气信息设计--> <view class='detail'> <view class='bar'> <view class='box'>湿度</view> <view class='box'>气压</view> <view class='box'>能见度</view> </view> <view class='bar'> <view class='box'>{{now.humidity}} %</view> <view class='box'>{{now.pressure}} hPa</view> <view class='box'>{{now.vis}} km</view> </view> <view class='bar'> <view class='box'>风向</view> <view class='box'>风速</view> <view class='box'>风力</view> </view> <view class='bar'> <view class='box'>{{now.windDir}}</view> <view class='box'>{{now.windSpeed}} km/h</view> <view class='box'>{{now.windScale}} 级</view> </view> </view> </view>
index.wxss
/**index.wxss**/ /*文本样式*/ text{ font-size: 80rpx; color:#081746; } /*天气图标样式*/ image{ width: 220rpx; } /*区域 4 整体样式*/ .detail{ width: 100%; display: flex; flex-direction: column; } /*区域 4 单元行样式*/ .bar{ display: flex; flex-direction: row; margin: 35rpx 0; /*外边距*/ } /*区域 4 单元格样式*/ .box{ width: 33.3%; text-align: center; }
app.json
{ "pages": [ "pages/index/index" ], "window": { "navigationBarBackgroundColor": "#003153", "navigationBarTitleText": "今 日 天 气", "navigationBarTextStyle": "white" }, "sitemapLocation": "sitemap.json" }
app.wxss
/**app.wxss**/ /*页面容器样式*/ .container{ height: 100vh; /*高度100视窗*/ display: flex; /*flex布局*/ flex-direction: column; /*垂直布局*/ align-items: center; /*水平居中*/ justify-content: space-around; /*垂直方向分散分布*/ }