【微信小程序】天气查询

课程 中国海洋大学22夏《移动软件开发》
实验名称 实验2:天气查询小程序

一、实验目标

1、掌握服务器域名配置和临时服务器部署;

2、掌握 wx.request 接口的用法。

二、实验步骤

1. 准备工作

  1. API 密钥申请

    选择可提供全球气象数据服务接口的 和风天气API ;

    官方网址: https://www.qweather.com

    此处选择 天气API 进行注册。

    由网址 控制台 | 和风天气 (qweather.com) 进入控制台查看账号信息。

    在左侧栏选择 应用管理。

    选择免费开发版。

    填写应用名称。

    选择 Web API 

    填写 KEY 的名称

    点击 创建 即可获取 KEY 。

  2. 微信小程序后台域名配置

    • 由以下网址进入和风天气开发平台获取开发版 API 。

    https://dev.qweather.com/docs/api/weather/weather-now/

    • 登陆微信公众平台的小程序后台,进入 开发 -> 开发管理 -> 开发设置 下的服务器域名。

    将我们要用到的 API 的域名

    https://devapi.qweather.com

    添加到request合法域名里面。

    保存后可以看到修改结果。

  3. 素材下载 实验中需要的天气图片、utils.js下载地址为:

    https://gaopursuit.oss-cn-beijing.aliyuncs.com/2022/demo2_file.zip

2. 创建项目

项目名称与目录为默认;

AppID点击右侧三角后即可选择;

后端服务选择不适用云服务;

模板选择官方的JavaScript。

3. 页面配置

  1. 新建项目

  2. 创建页面文件 并 删除和修改文件

  • [删除] utils文件夹及其内部所有内容;

  • [删除] app.json 文件内 pages 属性中的 "pages/logs/logs",并[删除] pages 文件夹下的 logs 目录机器内部所有内容;

  • [删除] index.wxml 及 index.wxss 文件中全部的代码;

  • [删除] index.js 中的全部代码,并输入关键词 page 找到并补全函数。

  • [删除] app.wxss 文件中全部的代码;

  • [删除] app.js 中的全部代码,并输入关键词 app 找到并补全函数。

  1. 创建图表文件夹

    • 在中间的目录结构单击 右键 新建 images 文件夹。

    右键单击 image 文件夹,点击 [在资源管理器中打开] 。将下载好的天气图片放入此文件夹。

    • 将下载的 utils 文件夹放入 index 目录下。

4. 视图设计

  1. 导航栏

    修改 app.json 中的 windows 属性代码为:

    {
      "pages": [
        "pages/index/index"
      ],
      "window": {
        "navigationBarBackgroundColor": "#003153",
        "navigationBarTitleText": "今 日 天 气",
        "navigationBarTextStyle": "white"
      },
      "sitemapLocation": "sitemap.json"
    }

    字体颜色:普鲁士蓝 ;导航栏标题:今 日 天 气;导航栏字体颜色:白色。

  2. 页面设计

    页面上主要包含四个区域:

    • 区域 1:地区选择器,用户可以自行选择查询的省、市、区; picker 组件;

    • 区域 2:显示当前城市的温度和天气状态的文字说明; text 组件;

    • 区域 3:显示当前城市的天气图标; image 组件;

    • 区域 4:分多行显示其他天气信息,例如湿度、气压、能见度和风向等;

      view 组件,并定义 class='detail';

      区域4内单元行:4个 view 组件,并定义class='bar';

      区城4内单元格:每行3个 view 组件,并定义class='box'。

    • 页面整体:view 组件,并定义 class= 'container';

    1. 整体容器设计

    • 定义页面容器 ( 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;  /*垂直方向分散分布*/
        }

    1. 地区选择器设计

      使用 picker 组件实现。

      index.wxml 代码:

      <!--index.wxml-->
      <view class="container">
        <!--区域 1:地区选择器-->
        <picker mode="region">
          <view>北京市</view>
        </picker>
      </view>

      picker 组件内部填写任意一个城市,点击此城市名后下方弹出选择控制台。

    2. 文本设计

      index.wxml 内添加代码:

      <!--index.wxml-->
      <view class="container">
        <!--区域 1:地区选择器-->
        ……
        <!--区域 2:文本设计-->
        <text>19°C 晴</text>
      </view>

      index.wxss 添加文本样式代码:

      /*文本样式*/
      text{
        font-size: 80rpx;
        color:#081746;
      }

    3. 天气图标设计

      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;
      }

    4. 多行天气信息设计

      使用 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. 逻辑实现

  1. 更新省、市、区信息

    修改 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
        });
      }
    })

  2. 获取实况天气数据

    在 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();
      }

  3. 更新页面天气信息

    由网址

    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. 遇到的问题及解决方法

  1. API 调用出错

    使用下载好的 utils 文件夹中的文件。

    在 index.js 中加入如下语句。

    //index.js
    const util = require('/utils/util.js');

  2. 无法获取天气信息

    教程中的参数与目前版本使用的参数有所不同。

    从开发平台拿到 API 后获取天气信息,即可活得天气相关参数。

  3. 位置无法获取

    HeWeather[0].now 属性目前版本已无法使用。

    相关语句修改为

    location: util.getLocationID(that.data.region[1]),
    that.setData({now:res.data.now});

  4. 多云天气无法显示图表

    多云天气图标编号为 151;下载的多云图片编号为 153。修改文件名即可。

2. 总结与体会

  1. 熟悉并学习使用免费的 API,十分方便。

  2. 小程序开发环境更新换代十分迅速。大部分时间花在了找新版本的 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;  /*垂直方向分散分布*/
}

猜你喜欢

转载自blog.csdn.net/weixin_51079437/article/details/126397136