【微信小程序项目】——十分钟开发网络API·天气查询小程序、天气查询,美观简约,简单易上手

【实验目的】

  1. 复习小程序项目新建过程
  2. 掌握配置https域名的方式
  3. 使用微信网络请求能力获取天气预报
  4. 使用腾讯提供的网络通信API,调用第三方提供的API

PART I 准备工作

        1. API密钥申请(非必做

本小节主要介绍如何申请获得开源API的密钥。这里选择了可以提供全球气象数据服务接口的和风天气API,其官方网址为https://www.heweather.com/(如图1所示)。

官方网址现已改为https://www.qweather.com/

图1 “和风天气”官方主页(访问时间:2018.10.27 10:26)

点击“天气API”,跳转到https://dev.qweather.com/。用户选择 “免费用户”类型然后使用邮箱进行注册并激活后,可以获取三天之内全球各地区的实时天气,免费接口调用流量为1000次/天、频率为200次/分钟,该数据基本可以满足读者的开发学习需求。

注册完毕之后,点击“控制台”按钮,可以访问https://id.qweather.com/#/login?redirect=https%3A%2F%2Fconsole.qweather.com来查看账号信息,用户登陆后即可看到开发者申请到的个人认证key,如图2所示。

图2个人认证key查询页面(访问时间:2018.10.27 10:27)

开发者需记录上述页面中的个人认证key,该信息在小程序发出网络请求时会作为身份识别的标识一并发送给和风天气的第三方服务器。至此,开源API的密钥申请就已经顺利完成,读者可以进行下一节的学习,了解如何调用API获取气象数据。

        1. API调用方法

目前免费用户可以调用的最新版接口地址为:https://dev.qweather.com/docs/api/weather/weather-now/,其服务器节点在中国境内。该接口地址后面追加不同的关键词将获取不同种类的气象数据信息,例如alarm为天气自然灾害预警、读者可以访问官方文档开发文档 | 和风天气开发平台,以及https://dev.qweather.com/docs/api/,了解各类关键词的使用方法。

本示例将选用关键词weather/now进行实况天气数据的获取。实况天气即为当前时间点的天气状况以及温湿风压等气象指数,具体包含的数据:体感温度、实测温度、天气状况、风力、风速、风向、相对湿度、大气压强、降水量、能见度等。目前该接口允许查询的城市覆盖范围为全球任意一个城市。

基于关键词weather/now的接口具有两个必填参数和两个可选参数,如表1所示。

表1 weather接口参数一览表

参数名称

参数类型

解释

location

必填参数

用于规定需要查询的城市。可以填入城市名称(国内城市填中文或拼音均可)、城市ID、IP地址或经纬度。

例如:

location=北京、location=beijing(城市名称)

location=CN101010100(城市ID)

location=60.194.130.1(IP地址)

location=120.343,36.088(经纬度)

key

必填参数

需要填入用户的个人认证key字符串。接口将通过该数据判断是否为授权用户,并可以进一步判断是否为付费用户。

例如:key=58cde137c76f44f5bc7885fc1e711aa9

lang

可选参数

用于指定数据的语言版本,不添加lang参数则默认为简体中文。

例如:lang=en

需要注意的是,国内某些特定数据(例如生活指数、空气质量等)不支持多语言版。

unit

可选参数

单位选择,公制(m)或英制(i),默认为公制单位。

例如:unit=i

详见表5-度量衡单位一览表。

其中与unit参数相关公制和英制单位对比如表2所示。

表2 度量衡单位一览表

数据项

公制单位

英制单位

温度

摄氏度 ℃

华氏度 ℉

风速

公里/小时 km/h

英里/小时 mile/h

能见度

公里 km

英里 mile

大气压强

百帕 hPa

百帕 hPa

降水量

毫米 mm

毫米 mm

PM2.5

微克/立方米 μg/m3

微克/立方米 μg/m3

PM10

微克/立方米 μg/m3

微克/立方米 μg/m3

O3

微克/立方米 μg/m3

微克/立方米 μg/m3

SO2

微克/立方米 μg/m3

微克/立方米 μg/m3

CO

毫克/立方米 mg/m3

毫克/立方米 mg/m3

NO2

微克/立方米 μg/m3

微克/立方米 μg/m3

注:部分数据项无论选择何种单位均会使用公制单位。

https://devapi.qweather.com/v7/weather/now?location=101010200&key=58cde137c76f44f5bc7885fc1e711aa9

开发版 https://devapi.qweather.com/v7/weather/now?location=101010100&key=你的KEY

以前强调过:音频、视频、图片,若是网络地址,一定要在浏览器中打开试一试。

现在又增加了一条:网络服务,一定要在浏览器中打开试一试。

免费用户调用接口的常见语法格式如下:

https://free-api.heweather.com/s6/weather/now?[parameters]

https://devapi.qweather.com/v7/weather/now?[请求参数]

其中[parameters]需要替换成使用到的参数,多个参数之间使用&符号隔开。

https://free-api.heweather.com/s6/weather/now?location=shanghai&key=58cde137c76f44f5bc7885fc1e711aa9

    例如,使用拼音查询上海市天气数据的写法如下:

https://free-api.heweather.com/s6/weather/now?location=shanghai&key=1234abcd

注:其中key的值1234abcd为随机填写的内容,请在实际开发中将其替换为真实的个人认证key,否则接口将无法获取数据。key=58cde137c76f44f5bc7885fc1e711aa9

可以直接将这段地址输入到浏览器地址栏中测试数据返回结果,如图3所示。

图3免费天气查询接口返回结果页面(访问时间:2018.10.27 10:59)

由上图可见,指定城市的天气数据返回结果是json数据格式的文本内容,其中包含的数据是以“名称:值”的形式存放。

为方便用户查看,将图3返回的数据内容整理格式后如下:

{

"HeWeather6":[

{

"basic":{

"cid":"CN101020100",

"location":"上海",

"parent_city":"上海",

"admin_area":"上海",

"cnty":"中国",

"lat":"31.23170662",

"lon":"121.47264099",

"tz":"+8.00"

},

"update":{

"loc":"2018-10-27 10:45",

"utc":"2018-10-27 02:45"

},

"status":"ok",

"now":{

"cloud":"0",

"cond_code":"100",

"cond_txt":"晴",

"fl":"17",

"hum":"19",

"pcpn":"0.0",

"pres":"1024",

"tmp":"19",

"vis":"10",

"wind_deg":"315",

"wind_dir":"西北风",

"wind_sc":"1",

"wind_spd":"4"

}

}

]

}

返回的字段说明如表3所示。

表3 实况天气返回字段说明

basic 基础信息

参数

描述

示例值

location

地区/城市名称

海淀

cid

地区/城市ID

CN101080402

lat

地区/城市纬度

39.956074

lon

地区/城市经度

116.310316

parent_city

该地区/城市的上级城市

北京

admin_area

该地区/城市所属行政区域

北京

cnty

该地区/城市所属国家名称

中国

tz

该地区/城市所在时区

8

update 接口更新时间

参数

描述

示例值

loc

当地时间,24小时制,格式yyyy-MM-dd HH:mm

2017/10/25 12:34

utc

UTC时间,24小时制,格式yyyy-MM-dd HH:mm

2017/10/25 4:34

now 实况天气

参数

描述

示例值

fl

体感温度,默认单位:摄氏度

23

tmp

温度,默认单位:摄氏度

21

cond_code

实况天气状况代码

100

cond_txt

实况天气状况描述

wind_deg

风向360角度

305

wind_dir

风向

西北

wind_sc

风力

3

wind_spd

风速,公里/小时

15

hum

相对湿度

40

pcpn

降水量

0

pres

大气压强

1020

vis

能见度,默认单位:公里

10

cloud

云量

23

status 接口状态

参数

描述

示例值

status

接口状态,具体含义请参考表5-接口状态码及错误码

ok

其中参数status的状态码及错误码如表4所示。

表4 接口状态码及错误码说明

代码

说明

ok

数据正常

invalid key

错误的key,请检查你的key是否输入以及是否输入有误

unknown location

未知或错误城市/地区

no data for this location

该城市/地区没有你所请求的数据

no more requests

超过访问次数,需要等到当月最后一天24点(免费用户为当天24点)后进行访问次数的重置或升级你的访问量

param invalid

参数错误,请检查你传递的参数是否正确

too fast

超过限定的QPM,请参考QPM说明

dead

无响应或超时,接口服务异常请联系我们

permission denied

无访问权限,你没有购买你所访问的这部分服务

sign error

签名错误,请参考签名算法

    如果接口无法正确获取数据可以根据状态码对比上表查询原因。

用户可以根据指定的名称找到对应的数据值,例如在实况天气数据now中可以查到当前城市的温度,对应的字段节选如下:

"tmp":"19"

上述代码表示当前城市的温度为19摄氏度。

        1. 服务器域名配置必做

每一个小程序在与指定域名地址进行网络通信前都必须将该域名地址添加到管理员后台白名单中。因此本示例需要对域名地址https://free-api.heweather.com进行服务器配置。

小程序开发者登陆mp.weixin.qq.com进入管理员后台,选择【设置】—【开发设置】—【服务器域名】即可进行添加或修改需要进行网络通讯的服务器域名地址,如图4所示。

图4 服务器域名配置

将当前需要使用的接口添加到request合法域名】栏目中,配置完成后再登陆小程序开发工具就可以允许小程序与指定的服务器域名地址之间的网络通讯了,注意每个月只可以申请修改5次服务器域名配置。

PART II 小程序项目新建(必做

本次项目创建选择空白文件夹weatherDemo,注意请取消勾选“建立普通快速启动模板”选项,以免自动生成代码影响手动编写。效果如图5所示。

图5小程序项目填写效果示意图

单击“确定”按钮完成项目创建,然后准备手动创建页面配置文件。

PART III 页面配置

        1. 创建应用文件

首先进行app.json文件的创建,并在app.json文件中输入一对{}符号,然后Ctrl+S快捷键进行保存。后面用同样的方法新建app.js和app.wxss文件,这两个文件暂时保持内容空白关闭即可。全部完成后的目录结构如图6所示。

图6应用文件创建完成

        1. 创建页面文件

应用文件创建完毕后,在根目录中创建自定义文件夹pages用于存放页面文件。本次项目只有一个页面文件,因此只需要在pages目录下创建index文件夹和其内部的wxml、wxss、js以及json四个同名文件。完成后的目录结构如图7所示。

图7页面文件创建完成

此时app.json会自动生成页面配置代码,如图8所示。

图8 app.json自动生成页面配置代码

        1. 创建其他文件

接下来创建其他自定义文件,本项目主要还需要一个文件夹用于存放天气图标素材。文件夹名称由开发者自定义(例如images),创建方式与pages文件夹创建方式完全相同。

本项目用到的图标素材共计75个,均来源于和风天气官网,图标合集如图9所示。

图9 天气图标素材展示

其中图标文件名为对应的天气代码,后缀名均为.png。需要注意的是,部分图标文件名带有字母n表示夜间天气图标,例如100n.png。

对目录结构中的images文件夹右击,选择“硬盘打开”,在该文件夹中新建二级目录weather_icon,然后将图标文件全部复制粘贴进去。完成后的目录结构如图10所示。

 

图10页面文件创建完成

此时文件配置就全部完成,下一节将正式进行页面布局和样式设计。

PART IV 视图设计必做

        1. 导航栏设计

小程序默认导航栏是黑底白字的效果,因此需要在app.json中自定义导航栏标题和背景颜色。更新后的app.json文件代码如下:

{

  "pages": [

    "pages/index/index"

  ],

  "window": {

    "navigationBarBackgroundColor": "#3883FA",

    "navigationBarTitleText": "今日天气"

  }

}

上述代码可以更新所有页面的导航栏标题文本为“今日天气”、背景颜色为蓝色(#3883FA)。预览效果如图11所示

图11自定义导航栏效果

        1. 页面设计

页面上主要包含4个区域,具体内容解释如下:

  1. 区域1:地区选择器,用户可以自行选择查询的省市区;
  2. 区域2:显示当前城市的温度和天气状态的文字说明;
  3. 区域3:显示当前城市的天气图标;
  4. 区域4:分多行显示其他天气信息,例如湿度、气压、能见度和风向等。

面板之间需要有一定的间隔距离,设计图如图12所示。

图12页面设计图

计划使用组件如下:

  1. 页面整体:<view>组件,并定义class='container';
  2. 区域1:<picker>组件;
  3. 区域2:<text>组件;
  4. 区域3:<image>组件;
  5. 区域4:<view>组件,并定义class='detail';
  6. 区域4内单元行:4个<view>组件,并定义class= 'bar';
  7. 区域4内单元格:每行3个<view>组件,并定义class='box'。
  1. 整体容器设计

首先定义页面容器<view>,WXML(pages/index/index.wxml)代码片段如下:

<view class='container'>

</view>

在app.wxss中设置容器样式,代码片段如下:

/*背景容器样式*/

.container{

  height: 100vh; /*高度为100视窗,写成100%无效*/

  display: flex; /*flex布局模型*/

  flex-direction: column; /*垂直布局*/

  align-items: center;/*水平方向居中*/

}

当前效果如图13所示。

图13页面预览效果

由于还没添加组件元素,因此尚看不出来flex布局模型效果。

  1. 区域1(省市区选择器)设计

区域1需要使用<picker>组件来实现一个省市区选择器,用户点击可切换选择其他城市。

WXML(pages/index/index.wxml)代码片段修改如下:

<view class='container'>

  <!--区域1:地区选择器-->

  <picker mode='region'>

    <view>北京市</view>

  </picker>

</view>

在<picker>组件内部是开发者任意填写的一个城市名称,当前效果如图14所示。

页面初始效果

点击城市名称时效果

图14区域1预览效果

由图可见,点击城市名称时会从底部弹出控件,用户可以进行省市区选择。

  1. 区域2(文本)设计

区域2需要使用<text>组件实现一个单行天气信息,包括当前城市的温度和天气状况。

WXML(pages/index/index.wxml)代码片段修改如下:

<view class='container'>

  <!--区域1:地区选择器-->

  …代码略

  <!--区域2:单行天气信息-->

  <text>19°C 晴</text>

</view>

WXSS(pages/index/index.wxss)代码片段如下:

/*文本样式*/

text{

  font-size: 80rpx;

  color:#3C5F81;

}

当前效果如图15所示。

图15区域2预览效果

当前显示的文本内容由开发者自定义,待查询到实际数据后将动态更新文本内容。

  1. 区域3(天气图标)设计

区域3需要使用<image>组件展示当前城市的天气图标。

WXML(pages/index/index.wxml)代码片段修改如下:

<view class='container'>

  <!--区域1:地区选择器-->

  …代码略

  <!--区域2:单行天气信息-->

  …代码略

  <!--区域3:天气图标-->

  <image src='/images/weather_icon/999.png' mode='widthFix'></image>

</view>

WXSS(pages/index/index.wxss)代码片段如下:

/*图标样式*/

image{

  width: 220rpx;

}

当前效果如图16所示。

图16区域3预览效果

“N/A”表示的天气状况为“未知”,待查询到实况数据后将动态更新图标内容。

  1. 区域4(多行天气信息)设计

区域4需要使用<view>组件展示多行天气信息。

WXML(pages/index/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>

WXSS(pages/index/index.wxss)代码片段如下:

/*区域4整体样式*/

.detail{

  width: 100%;

  display: flex;

  flex-direction: column;

}

/*区域4单元行样式*/

.bar{

  display: flex;

  flex-direction: row;

  margin: 20rpx 0;

}

/*区域4单元格样式*/

.box{

  width: 33.3%;

  text-align: center;

}

当前效果如图17所示。

图17区域4预览效果

当前为开发者自定义数据,待查询到实况数据后将动态更新区域4的内容。此时页面设计就全部完成了,接下来需要进行逻辑实现。

PART V 逻辑实现(必做

        1. 更新省市区信息

首先修改<picker>组件中的“北京市”为{ {region}},然后为<picker>组件追加自定义bindchange事件,用于监听选项变化。

WXML(pages/index/index.wxml)代码片段修改如下:

<view class='container'>

  <!--区域1:地区选择器-->

  <picker mode='region' bindchange='regionChange'>

    <view>{ {region}}</view>

  </picker>

</view>

由于省市区选择器的返回结果是数组的形式,因此在JS文件的data中定义region为包含了省、市、区三个项目的数组,初始城市信息由开发者自定义。

JS(pages/index/index.js)代码片段修改如下:

Page({

  /**

   * 页面的初始数据

   */

  data: {

    region:['安徽省','芜湖市','镜湖区']

  },

  /**

   * 更新省市区信息

   */

  regionChange: function(e) {

    this.setData({region: e.detail.value});

  },

})

运行效果如图18所示。

  1. 重新选择城市

  1. 更新省市区信息

图18更新省市区信息

由图可见,当前已经可以自行切换到国内任意省市区。

        1. 获取实况天气数据

在JS文件中使用自定义函数getWeather进行实况天气数据的获取。由于非直辖市无法查询到具体的区,因此后续的天气查询以城市作为查询依据。

JS(pages/index/index.js)代码片段修改如下:

Page({

  /**

   * 获取实况天气数据

   */

  getWeather: function () {

    var that = this;//this不可以直接在wxAPI函数内部使用

    wx.request({

      url: 'https://free-api.heweather.com/s6/weather/now',  //后端程序

      data:{

        location:that.data.region[1],

        key:'58cde137c76f44f5bc7885fc1e711aa9'  //也可以换成其他的和风天气密钥key

      },

      success:function(res){

        console.log(res.data);

      }

    })

  },

})

将上述函数在生命周期函数onLoad和自定义函数regionChange中分别进行调用,表示当页面加载时和切换城市时均主动获取一次实况天气数据。

JS(pages/index/index.js)代码片段修改如下:

Page({

  /**

   * 更新省市区信息

   */

  regionChange: function(e) {

    this.setData({region: e.detail.value});

    this.getWeather();//更新天气

  },

  /**

   * 生命周期函数--监听页面加载

   */

  onLoad: function(options) {

    this.getWeather();//更新天气

  },

})

在联网状态下保存后重新运行会在Console控制台得到第三方服务器发回的JSON数据,如图19所示。

图19 Console控制台获取到服务器返回数据

由图可见,实况天气数据包含在HeWeather6[0].now属性中。更新getWeather函数,将该属性存入到JS文件的data中,JS(pages/index/index.js)代码片段修改如下:

Page({

  /**

   * 获取实况天气数据

   */

  getWeather: function () {

    var that = this;//this不可以直接在wxAPI函数内部使用

    wx.request({

      url: 'https://free-api.heweather.com/s6/weather/now',

      data:{

        location:that.data.region[1],

        key:'58cde137c76f44f5bc7885fc1e711aa9'  //也可以换成其他的和风天气密钥key

      },

      success:function(res){

        that.setData({now:res.data.HeWeather6[0].now});

      }

    })

  },

})

此时重新运行将在AppData面板查到已经被记录的天气数据,如图20所示。

图20 AppData面板获取到数据

现在只需要将这些数据更新到页面上即可显示出来。

        1. 更新页面天气信息

将WXML页面上所有的临时数据都替换成{ {now.属性}}的形式,例如温度是{ {now.tmp}}。

WXML(pages/index/index.wxml)代码片段修改如下:

<view class='container'>

  <!--区域1:地区选择器-->

  …代码略

  <!--区域2:单行天气信息-->

  <text>{ {now.tmp}}°C { {now.cond_txt}}</text>

  <!--区域3:天气图标-->

  <image src='/images/weather_icon/{ {now.cond_code}}.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.hum}} %</view>

      <view class='box'>{ {now.pres}} 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.wind_dir}}</view>

      <view class='box'>{ {now.wind_spd}} km/h</view>

      <view class='box'>{ {now.wind_sc}} 级</view>

    </view>

  </view>

</view>

运行效果如图21所示。

图21 实况天气数据显示效果

需要注意的是,在网速受限的情况下可能不能立刻获取到数据,因此最好在JS文件的data中为now规定自定义初始数据,获取到实际数据前可以临时显示这些数据。

JS(pages/index/index.js)代码片段修改如下:

Page({

  /**

   * 页面的初始数据

   */

  data: {

    region: ['安徽省', '芜湖市', '镜湖区'],

    now:{

      tmp:0,

      cond_txt:'未知',

      cond_code:'999',

      hum:0,

      pres:0,

      vis:0,

      wind_dir:0,

      wind_spd:0,

      wind_sc:0

    }

  },

})

在网速受限的状态下,初始数据显示效果如图22所示。

图22 初始数据显示效果

    此时项目就全部完成了。

PART VI 课后思考

可以使用其他天气接口制作更丰富的效果。

猜你喜欢

转载自blog.csdn.net/lijingxiaov5/article/details/124802910