移动软件开发-实时天气获取
一、实验目标
1、学习使用快速启动模板创建小程序的方法;
2、学习不使用模板手动创建小程序的方法。
3、学习使用wx.request
接口向第三方API发送请求,获取实时天气数据
4、学习阅读API开发文档
5、通过开发天气查询小程序,熟悉小程序的视图设计和数据绑定方法。
二、实验步骤
使用和风天气API
-
注册获取key
-
阅读开发文档,实现实时天气获取主要用到两个API
-
一是https://geoapi.qweather.com/v2/city/lookup, 传两个参数:location(中文地址,如朝阳区),key
根据区、县的id获取天气信息 -
二是https://devapi.qweather.com/v7/weather/now,传两个参数:location(location的id), key
-
根据获取的信息,进行解析,筛选所需数据进行展示
-
三、程序运行结果
初始页面:显示默认的地区信息和天气数据。
地区选择后:用户选择不同的省、市、区后,页面实时更新天气信息。
四、可能遇到下列问题
问题:
查询实时天气的官方api不能正常使用: 用Postman检验发现403
![请添加图片描述](https://i-blog.csdnimg.cn/direct/c2899976a032402c8515b729a35a1cb7.png)
将https://api.qweather.com/v7/weather/now替换为https://devapi.qweather.com/v7/weather/now
API请求失败问题:在开发过程中遇到 API 请求失败的情况,原因是未正确配置合法域名。通过在微信开发者工具中添加和风天气的 API 域名解决了该问题。
数据绑定问题:在初次获取数据时,页面未能实时更新。通过调试发现,是因为 setData
方法未能及时调用。调整代码后问题解决。
代码下附:
<!-- index.wxml -->
<view class='container'>
<!-- 区域1:地区选择器 -->
<picker mode='region' bindchange='regionChange' class='region-picker'>
<view>{{region}}</view>
</picker>
<!-- 区域2:单行天气信息 -->
<view class='weather-info'>
<text class='temp'>{{now.temp}}℃</text>
<text class='description'>{{now.text}}</text>
</view>
<!-- 区域3:天气图标 -->
<image src='/static/{{now.icon}}.svg' mode='widthFix' class='weather-icon'></image>
<!-- 区域4:多行天气信息 -->
<view class='detail'>
<view class="bar">
<view class='box'>
<text>湿度</text>
<text class='value'>{{now.humidity}}%</text>
</view>
<view class='box'>
<text>气压</text>
<text class='value'>{{now.pressure}}hPa</text>
</view>
<view class='box'>
<text>能见度</text>
<text class='value'>{{now.vis}}km</text>
</view>
</view>
<view class="bar">
<view class='box'>
<text>风向</text>
<text class='value'>{{now.windDir}}</text>
</view>
<view class='box'>
<text>风速</text>
<text class='value'>{{now.windSpeed}}km/h</text>
</view>
<view class='box'>
<text>风力</text>
<text class='value'>{{now.windScale}}级</text>
</view>
</view>
</view>
</view>
<!-- index.wxss -->
.container {
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
background: linear-gradient(to bottom, #f0f4f8, #d9e2ec);
padding: 20rpx;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 20rpx;
}
.region-picker {
width: 80%;
padding: 10rpx 20rpx;
background: #ffffff;
border-radius: 10rpx;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
text-align: center;
font-size: 30rpx;
color: #3C5F81;
}
.weather-info {
display: flex;
flex-direction: row;
align-items: baseline;
justify-content: center;
}
.temp {
font-size: 100rpx;
color: #FF6B6B;
font-weight: bold;
}
.description {
font-size: 50rpx;
color: #3C5F81;
margin-left: 20rpx;
}
.weather-icon {
width: 220rpx;
animation: fadeIn 1s ease-in-out;
}
.detail {
width: 90%;
display: flex;
flex-direction: column;
background: #ffffff;
border-radius: 10rpx;
padding: 20rpx;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.bar {
display: flex;
flex-direction: row;
margin: 20rpx 0;
}
.box {
width: 33.3%;
text-align: center;
font-size: 30rpx;
color: #3C5F81;
}
.value {
font-size: 35rpx;
color: #FF6B6B;
font-weight: bold;
margin-top: 10rpx;
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
<!-- index.js -->
Page({
/**
* 页面的初始数据
*/
data: {
region:['安徽省','芜湖市','镜湖区'],
id: 101220306,
now: {
tmp: 0,
cond_txt:'未知',
cond_code:'999',
hum: 0,
pres: 0,
vis: 0,
wind_dir: 0,
wind_spd: 0,
wind_sc: 0,
icon:100,
}
},
regionChange: function(e) {
this.setData({region: e.detail.value})
this.getId(this.data.region[2])
},
getId: function(city) {
city = city.slice(0, -1)
let that = this
wx.request({
url: 'https://geoapi.qweather.com/v2/city/lookup',
data: {
location: city,
key: "36b3a208d4894f9ab29eca523ab0919d"
},
success: function(res) {
console.log({id: res.data.location[0].id})
that.setData({id: res.data.location[0].id})
that.getWeather()
}
})
},
getWeather: function() {
console.log(this.data.id)
let that = this
wx.request({
url: 'https://devapi.qweather.com/v7/weather/now',
data: {
location: that.data.id,
key: "36b3a208d4894f9ab29eca523ab0919d"
},
success: function(res) {
console.log(res.data)
that.setData({now: res.data.now})
}
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getId(this.data.region[1])
},
/**
* 生命周期函数--监听页面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函数--监听页面显示
*/
onShow: function () {
},
/**
* 生命周期函数--监听页面隐藏
*/
onHide: function () {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload: function () {
},
/**
* 页面相关事件处理函数--监听用户下拉动作
*/
onPullDownRefresh: function () {
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
},
/**
* 用户点击右上角分享
*/
onShareAppMessage: function () {
}
})