微信小程序-天气API的使用

一、实现效果

首次打开显示默认城市-广州(可自定义)的天气
在这里插入图片描述
点击获取当前位置(首次打开),跳出弹框请求授权
在这里插入图片描述
非首次打开(已授权)则直接显示本地的天气信息,并将当前位置存入本地缓存,下次打开小程序直接显示本地的天气信息
在这里插入图片描述

二、实现思路

  1. 调用百度开放平台接口获取天气数据
  2. 调用百度开放平台的逆地址解析接口获取当前位置
  3. 调用当前的位置信息获取本地的天气信息
  4. 将获取的当前位置数据存入设备中(本地缓存),下次打开小程序直接显示当前位置的天气信息

三、页面布局

头部(top)城市天气搜索框和获取当前位置的组件
在这里插入图片描述
中部(body)天气的显示
在这里插入图片描述
底部(bottom)未来天气的显示
在这里插入图片描述

四、实施步骤

完整代码在文章后面提供

1. 调用百度开放平台天气API

需要先去百度开放平台申请秘钥ak  // 百度ak申请方法:点击此处跳转查看
在这里插入图片描述

2. 获取天气信息并进行赋值

在这里插入图片描述

3. 请求位置授权

在这里插入图片描述

4. 位置接口的初始化工作

小程序的内置接口只能获取到经纬度信息,无法直接获取位置信息,需要通过调用百度地图提供的接口解析成位置信息

  • 首先将js模块放入utils文件夹中(两个文件在文章末尾有提供)
    在这里插入图片描述
  • 然后在index.js中引入js模块

在这里插入图片描述

  • 在onload()函数中新建百度地图对象
    在这里插入图片描述

5. 调用百度地图位置服务接口将经纬度逆地址解析为位置信息

在这里插入图片描述

  • getLocation函数需要在app.json中声明permission字段
    在这里插入图片描述

  • 最后我们就能获取到位置信息了,将获取的位置再调用天气函数即可
    在这里插入图片描述

6.数据的本地缓存

存数据
在这里插入图片描述
取数据
(在onload函数中进行判断,若本地存在缓存的数据则直接进行赋值,显示当前位置的天气信息,若本地没有缓存的数据则显示默认城市广州的天气信息)
在这里插入图片描述

五、实现代码

index.js

// 定义城市、天气、温度、风级、图片,日期参数
var defaultcity, getTodayweather, gettip, getweather1, getweather2, getweather3
var localCity
var bmap = require('../../utils/bmap-wx.min.js'); //引入js模块
var BMap    //定义百度位置服务参数
  
// 调用百度天气接口获取天气数据
// 百度ak申请地址:http://lbsyun.baidu.com/apiconsole/key
var ak = '' // 在此处填写申请到的ak

Page({
  data: {},
  onLoad: function (e) {
    //将本地缓存中名为localCity的值取出来,赋值给localCity
    localCity = wx.getStorageSync('localCity')
    if (localCity) {
      defaultcity = localCity
      this.weather()
    } else {
      defaultcity = '广州'   // 默认城市名称
      this.weather()
    }
    BMap = new bmap.BMapWX({   //新建百度地图对象
      ak:ak
    });

  },
  // 动态获取input输入值 城市名称
  bindKeyInput: function (e) {
    defaultcity = e.detail.value
  },
  // 搜索城市
  search: function (e) {
    this.weather()
  },
  weather: function () {
    wx.showLoading({
      title: '加载中',
    })
    wx.request({
      url: 'https://api.map.baidu.com/telematics/v3/weather?output=json&ak=' + ak + '&location=' + defaultcity,
      success: res => {
        console.log(res.data)
        if (!res.data.results) {
          wx.showToast({
            title: '输入无法确定的地理位置信息或发生未知错误',
            icon: "none",
            duration: 2500
          })
          console.log('获取天气接口失败')
          return
        }
        //获取当前天气
        getTodayweather = res.data.results[0].weather_data[0]
        gettip = res.data.results[0].index[0].des
        //未来三日天气
        getweather1 = res.data.results[0].weather_data[1]
        getweather2 = res.data.results[0].weather_data[2]
        getweather3 = res.data.results[0].weather_data[3]
        this.setData({
          city: defaultcity,
          today: getTodayweather,
          tip: gettip,
          tomorrow1: getweather1,
          tomorrow2: getweather2,
          tomorrow3: getweather3,
        })
        wx.hideLoading()
      }
    })
  },

  //获取当前位置
  getMyLocation: function () {
    this.getUserLocation();
  },

  //请求位置授权 
  getUserLocation: function () {
    let that = this;
    wx.getSetting({
      success: (res) => {
        console.log(JSON.stringify(res))
        // res.authSetting['scope.userLocation'] == undefined    表示 初始化进入该页面
        // res.authSetting['scope.userLocation'] == false    表示 非初始化进入该页面,且未授权
        // res.authSetting['scope.userLocation'] == true    表示 地理位置授权
        if (res.authSetting['scope.userLocation'] != undefined && res.authSetting['scope.userLocation'] != true) {
          wx.showModal({
            title: '请求授权当前位置',
            content: '需要获取您的地理位置,请确认授权',
            success: function (res) {
              if (res.cancel) {
                wx.showToast({
                  title: '拒绝授权',
                  icon: 'none',
                  duration: 1000
                })
              } else if (res.confirm) {
                wx.openSetting({
                  success: function (dataAu) {
                    if (dataAu.authSetting["scope.userLocation"] == true) {
                      wx.showToast({
                        title: '授权成功',
                        icon: 'success',
                        duration: 1000
                      })
                      //再次授权,调用wx.getLocation的API
                      that.getLocation();
                    } else {
                      wx.showToast({
                        title: '授权失败',
                        icon: 'none',
                        duration: 1000
                      })
                    }
                  }
                })
              }
            }
          })
        } else if (res.authSetting['scope.userLocation'] == undefined) {
          //调用wx.getLocation的API
          that.getLocation();
        }
        else {    //res.authSetting['scope.userLocation'] == true
          //调用wx.getLocation的API
          that.getLocation();
        }
      }
    })
  },
  //百度地图逆地址解析服务
  getLocation: function () {
    var that = this
    BMap.regeocoding({
      success(res) {
        //var location = res.originalData.result.addressComponent.city      //获取市
        var location = res.originalData.result.addressComponent.district   //获取区
        defaultcity = location   //将获取的位置更换默认城市的值
        wx.setStorage({   //将获取的数据进行缓存,命名为localCity,值为location的值
          key: 'localCity',
          data: location,
        })
        console.log("当前地理位置信息", defaultcity)
        that.weather();  //调用天气函数
      },
      fail(res) {
        console.log("调用位置信息失败", res)
      }
    });
  },


})

index.wxml

<view class="page">

  <!-- top部分 -->
  <view class="top">
  <view class="nav">
    <input placeholder="输入城市名进行搜索" bindinput="bindKeyInput" bindconfirm="search" confirm-type="search"></input>
    <view class="icon">
      <icon type="search" size="25" bindtap="search" />
    </view>
  </view>
  <view bindtap="getMyLocation">
    获取当前位置 {{locationCity}}
  </view>
  </view>
  <!-- body部分 -->
  <view class="body">

    <view class="city">
      <text>{{city}}</text>
    </view>
  
    <view class="today">
      <text>{{today.date}}</text>
    </view>
  
    <view>
      <image src="{{today.dayPictureUrl}}" mode="aspectFit" style="width: 200rpx; height: 200rpx;margin-top:20rpx;" />
    </view>

    <view class="body-bottom">
         <view class="weather">
           <text>{{today.weather}}</text>
         </view>

          <view class="body-bottom-right">
              <view class="temp">
                 <text>{{today.temperature}}</text>
               </view>
               <view class="wind">
                 <text>{{today.wind}}</text>
               </view>
          </view>
    </view>
  
  </view>


  <!--bottom部分-->
  <view class="bottom">
    <view>
      <text>Tip:</text>
         <view class="tip">
             {{tip}}
           <!-- (抱歉,Tip接口数据丢失。接口修复将尽快更新哈) -->
          </view>
    </view>

    <view>
    <text>未来三日天气</text>
    <view class="future">

      <view class="future-weather-items">
        <view>{{tomorrow1.date}}</view>
        <view class="future-pic">    
            <image src="{{tomorrow1.dayPictureUrl}}" mode="aspectFit" />  
            <image src="{{tomorrow1.nightPictureUrl}}" mode="aspectFit" />        
        </view>
        <view>{{tomorrow1.weather}}</view>
        <view>{{tomorrow1.temperature}}</view>
      </view>

      <view class="future-weather-items">
        <view>{{tomorrow2.date}}</view>
        <view class="future-pic">
            <image src="{{tomorrow2.dayPictureUrl}}" mode="aspectFit" />
            <image src="{{tomorrow2.nightPictureUrl}}" mode="aspectFit" />
        </view>
        <view>{{tomorrow2.weather}}</view>
        <view>{{tomorrow2.temperature}}</view>
      </view>

      <view class="future-weather-items">
        <view>{{tomorrow3.date}}</view>
        <view class="future-pic">
            <image src="{{tomorrow3.dayPictureUrl}}" mode="aspectFit" />
            <image src="{{tomorrow3.nightPictureUrl}}" mode="aspectFit" />
        </view>
        <view>{{tomorrow3.weather}}</view>
        <view>{{tomorrow3.temperature}}</view>
      </view>

    </view>
</view>
  <view class="notes">数据来源:百度地图开放平台</view>
  </view>
  <!--页面最底部标示-->

</view>

index.wxss

page {
  background: -webkit-linear-gradient(bottom, lightblue, rgb(3, 171, 238), lightblue);
  color: #fff;
}

.page {
  margin: 25rpx 25rpx 0 25rpx;
}

/*top容器布局*/

.top {
  display: flex;
  flex-direction: column;
  height: 15vh;
}

.nav {
  display: flex;
  flex-direction: row;
  padding: 20rpx;
  background-color: #efefef;
  position: relative;
  margin-bottom: 20rpx;
  border-radius: 10rpx;
}

.input {
  width: 80%;
  font-size: 32rpx;
}

.icon {
  width: 10%;
  position: absolute;
  right: 0;
  bottom: 5rpx;
}

/*body容器布局*/

.body {
  height: 50vh;
  text-align: center;
  display: flex;
  flex-direction: column;
  justify-content: space-evenly;
}

.body-bottom {
  display: flex;
  flex-direction: row;
  justify-content: space-evenly;
  align-items: center;
}

.body-bottom-right {
  display: flex;
  flex-direction: column;
}

.city {
  font-size: 80rpx;
}

.today {
  margin-top: 25rpx;
  font-size: 34rpx;
}

.weather {
  font-size: 38rpx;
}

.wind {
  font-size: 40rpx;
  margin-top: 10rpx;
}

.temp {
  font-size: 40rpx;
  font-weight: bold;
  font-family: Arial, Helvetica, sans-serif;
}

input {
  color: #333;
}

/*bottom容器布局*/

.bottom {
  margin-top:25rpx;
  display: flex;
  flex-direction: column;
  justify-content: space-around;
  height: 35vh;
}

.tip {
  font-size: 28rpx;
  text-indent: 50rpx;
  padding-bottom: 40rpx;
  border-bottom: 1rpx solid #eee;
}

.future {
  display: flex;
  flex-direction: row;
}

.future-weather-items {
  width: 30%;
  background-color: rgba(129, 129, 129, 0.103);
  margin: 15rpx;
  text-align: center;
  font-size: 28rpx;
}

.future-pic {
  display: flex;
  flex-direction: row;
  justify-content: space-around;
}

.future-pic image {
  width: 65rpx;
  height: 65rpx;
  border-radius: 5%;
}

.notes {
  text-align: right;
  font-size: 18rpx;
  font-style: italic;
}

app.json

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "permission": {
    "scope.userLocation": {
      "desc": "你的位置信息将用于小程序天气接口的效果展示"
    }
  },
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  },
  "style": "v2",
  "sitemapLocation": "sitemap.json"
}
发布了4 篇原创文章 · 获赞 5 · 访问量 455

猜你喜欢

转载自blog.csdn.net/XiaoC_ong/article/details/104333941