微信小程序天气预报功能实现(支持自动定位,附源码)
时间:2022-07-04 14:06:29|栏目:JavaScript代码|点击: 次
前言
由于和风天气API的更新,之前写的那篇文章 可能会出现版本不兼容的 情况。所以 更新了 这个 使用新版API的 小程序。
效果图
天气API获取
这里我用的是和风天气的API,打开官网注册或者登陆你的账号
进入控制台,选择应用管理,新建应用(应用版本 选择 免费开发版,key的类型 选择 Web API)
创建成功后就可以看到 待会要用到的 key了
微信小程序后台域名配置
登陆小程序后台,分别点击开发和开发设置
点击修改,将我们要用到的 API的域名添加到request合法域名里面,https://devapi.qweather.com
和 https://geoapi.qweather.com
。
页面代码
.wxml
<view class="header-modular" wx:if="{{now}}"> <image class="bg-wave" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/bg_wave.gif"></image> <view class="row"> <view class="row location-wrap" bindtap="selectLocation"> <image class="icon" src="/images/icon_location.png"></image> <view class="title">{{City}} {{County}}</view> </view> </view> <view class="row"> <view class="tmp">{{now.temp}}°</view> <image class="icon-weather" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{now.icon}}.png"></image> </view> <view class="tips-wrap"> <view class="tips ">{{now.windDir}} {{now.windScale}}级</view> <view class="tips ">湿度 {{now.humidity}}%</view> <view class="tips ">气压 {{now.pressure}}Pa</view> </view> </view> <view class="card-modular " wx:if="{{hourly}}"> <view class="title">24小时预报</view> <view class="card-wrap"> <block wx:for="{{hourly}}" wx:key="index"> <view class="item hourly"> <view class="text-gray">{{item.time}}</view> <image class="icon" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{item.icon}}.png"></image> <view class="text-primary mb-32">{{item.temp}}°</view> <view>{{item.windDir}}</view> <view class="text-gray">{{item.windScale}}级</view> </view> </block> </view> </view> <view class="card-modular" wx:if="{{daily}}"> <view class="title">7天预报</view> <view class="card-wrap"> <block wx:for="{{daily}}" wx:key="index"> <view class="item daily"> <view>{{item.dateToString}}</view> <view class="text-gray">{{item.date}}</view> <image class="icon" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{item.iconDay}}.png"></image> <view class="text-primary ">{{item.tempMin}}°~{{item.tempMax}}°</view> <image class="icon" src="https://codermoyv.gitee.io/coder-moyv/assets/images/wechat/weather_custom/{{item.iconNight}}.png"></image> <view>{{item.windDirDay}}</view> <view class="text-gray">{{item.windScaleDay}}级</view> </view> </block> </view> </view>
.wxss
page { background-color: linear-gradient(to bottom, #ffffff,#ffffff, #F6F6F6); padding-bottom: 60rpx; } /* 工具类 */ .row { display: flex; align-items: center; } .mb-32{ margin-bottom: 32rpx; } /* 页面样式 */ .header-modular { height: 400rpx; background-color: #64C8FA; background: linear-gradient(to bottom, #56CCF2, #2F80ED); position: relative; padding: 30rpx; } .header-modular .bg-wave { width: 100vw; position: absolute; bottom: -2px; left: 0; right: 0; height: 120rpx; mix-blend-mode: screen; } .header-modular .location-wrap { color: #ffffff; font-weight: bold; font-size: 36rpx; } .header-modular .location-wrap .icon { width: 40rpx; height: 40rpx; margin-right: 8rpx; } .header-modular .tmp { font-size: 200rpx; /* font-weight: bold; */ color: #ffffff; margin-right: auto; } .header-modular .icon-weather { width: 200rpx; height: 200rpx; } .header-modular .tips-wrap { display: flex; justify-content: space-between; } .header-modular .tips { font-size: 28rpx; opacity: 0.8; color: #ffffff; flex: 1; } .header-modular .tips:nth-child(3) { text-align: right; } .header-modular .tips:nth-child(2) { text-align: center; } .card-modular { padding:0 30rpx; margin-top: 30rpx; } .card-modular>.title { font-size: 40rpx; font-weight: bold; position: relative; margin-left: 14rpx; margin-bottom: 16rpx; } .card-modular>.title::before { content: ""; position: absolute; left: -14rpx; top: 10rpx; bottom: 10rpx; width: 8rpx; border-radius: 10rpx; background-color: #2F80ED; } .card-modular .card-wrap { width: 690rpx; border-radius: 18rpx; background-color: #ffffff; box-shadow: 0 0 20rpx 0 rgba(0, 0, 0, 0.2); overflow-x: auto; white-space: nowrap; } .card-modular .card-wrap .item { display: inline-flex; flex-direction: column; align-items: center; font-size: 28rpx; padding: 18rpx 0; } .card-modular .card-wrap .item.hourly{ width: 138rpx; } .card-modular .card-wrap .item.daily{ width: 172.5rpx; } .card-modular .card-wrap .item .icon { width: 60rpx; height: 60rpx; margin: 64rpx 0; } .card-modular .card-wrap .item .text-gray { color: gray; } .card-modular .card-wrap .item .text-primary { color: #2F80ED; }
.js
const APIKEY = "";// 填入你申请的KEY Page({ /** * 页面的初始数据 */ data: { }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { this.getLocation() }, //选择定位 selectLocation() { var that = this wx.chooseLocation({ success(res) { //console.log(res) that.setData({ location: res.longitude + "," + res.latitude }) that.getWeather() that.getCityByLoaction() } , fail() { wx.getLocation({ type: 'gcj02', fail() { wx.showModal({ title: '获取地图位置失败', content: '为了给您提供准确的天气预报服务,请在设置中授权【位置信息】', success(mRes) { if (mRes.confirm) { wx.openSetting({ success: function (data) { if (data.authSetting["scope.userLocation"] === true) { that.selectLocation() } else { wx.showToast({ title: '授权失败', icon: 'none', duration: 1000 }) } }, fail(err) { console.log(err) wx.showToast({ title: '唤起设置页失败,请手动打开', icon: 'none', duration: 1000 }) } }) } } }) } }) } }) }, /** * 获取定位 */ getLocation() { var that = this wx.getLocation({ type: 'gcj02', success(res) { that.setData({ location: res.longitude + "," + res.latitude }) that.getWeather() that.getCityByLoaction() }, fail(err) { wx.showModal({ title: '获取定位信息失败', content: '为了给您提供准确的天气预报服务,请在设置中授权【位置信息】', success(mRes) { if (mRes.confirm) { wx.openSetting({ success: function (data) { if (data.authSetting["scope.userLocation"] === true) { wx.showToast({ title: '授权成功', icon: 'success', duration: 1000 }) that.getLocation() } else { wx.showToast({ title: '授权失败', icon: 'none', duration: 1000 }) that.setData({ location: "116.41,39.92" }) that.getWeather() that.getCityByLoaction() } }, fail(err) { console.log(err) wx.showToast({ title: '唤起设置页失败,请手动打开', icon: 'none', duration: 1000 }) that.setData({ location: "116.41,39.92" }) that.getWeather() that.getCityByLoaction() } }) } else if (mRes.cancel) { that.setData({ location: "116.41,39.92" }) that.getWeather() that.getCityByLoaction() } } }) } }) }, /** * 根据坐标获取城市信息 */ getCityByLoaction() { var that = this wx.request({ url: 'https://geoapi.qweather.com/v2/city/lookup?key=' + APIKEY + "&location=" + that.data.location, success(result) { var res = result.data if (res.code == "200") { var data = res.location[0] that.setData({ City: data.adm2, County: data.name }) } else { wx.showToast({ title: '获取城市信息失败', icon: 'none' }) } } }) }, /** * 获取天气 */ getWeather() { var that = this wx.showLoading({ title: '加载中', }) wx.request({ url: 'https://devapi.qweather.com/v7/weather/now?key=' + APIKEY + "&location=" + that.data.location, success(result) { var res = result.data //console.log(res) that.setData({ now: res.now }) } }) wx.request({ url: 'https://devapi.qweather.com/v7/weather/24h?key=' + APIKEY + "&location=" + that.data.location, success(result) { var res = result.data //console.log(res) res.hourly.forEach(function (item) { item.time = that.formatTime(new Date(item.fxTime)).hourly }) that.setData({ hourly: res.hourly }) } }) wx.request({ url: 'https://devapi.qweather.com/v7/weather/7d?key=' + APIKEY + "&location=" + that.data.location, success(result) { var res = result.data //console.log(res) res.daily.forEach(function (item) { item.date = that.formatTime(new Date(item.fxDate)).daily item.dateToString = that.formatTime(new Date(item.fxDate)).dailyToString }) that.setData({ daily: res.daily }) wx.hideLoading() } }) }, // 格式时间 formatTime(date) { const year = date.getFullYear() const month = date.getMonth() + 1 const day = date.getDate() const hour = date.getHours() const minute = date.getMinutes() const second = date.getSeconds() const weekArray = ["周日", "周一", "周二", "周三", "周四", "周五", "周六"] const isToday = date.setHours(0, 0, 0, 0) == new Date().setHours(0, 0, 0, 0) return { hourly: [hour, minute].map(this.formatNumber).join(":"), daily: [month, day].map(this.formatNumber).join("-"), dailyToString: isToday ? "今天" : weekArray[date.getDay()] } }, // 补零 formatNumber(n) { n = n.toString() return n[1] ? n : '0' + n }, /** * 生命周期函数--监听页面初次渲染完成 */ onReady: function () { }, /** * 生命周期函数--监听页面显示 */ onShow: function () { }, /** * 生命周期函数--监听页面隐藏 */ onHide: function () { }, /** * 生命周期函数--监听页面卸载 */ onUnload: function () { }, /** * 页面相关事件处理函数--监听用户下拉动作 */ onPullDownRefresh: function () { }, /** * 页面上拉触底事件的处理函数 */ onReachBottom: function () { }, /** * 用户点击右上角分享 */ onShareAppMessage: function () { } })
app.json
{ "pages": [ "pages/index/index" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "天气预报", "navigationBarTextStyle": "black" }, "permission": { "scope.userLocation": { "desc": "你的位置信息将用于天气预报定位" } }, "style": "v2", "sitemapLocation": "sitemap.json" }
注意问题(必看)
为了确保 小程序 可以 正常使用,请先在和风天气 控制台 升级为 个人开发者(ps:该升级需要上传实名信息)。
在js代码中,请将刚刚申请的key 填写进 APIKEY 里面
源码
Gitee源码 (欢迎Start)