微信小程序天氣預(yù)報(bào)功能實(shí)現(xiàn)(支持自動(dòng)定位,附源碼)
前言
由于和風(fēng)天氣API的更新,之前寫的那篇文章 可能會(huì)出現(xiàn)版本不兼容的 情況。所以 更新了 這個(gè) 使用新版API的 小程序。
效果圖


天氣API獲取
這里我用的是和風(fēng)天氣的API,打開官網(wǎng)注冊或者登陸你的賬號

進(jìn)入控制臺,選擇應(yīng)用管理,新建應(yīng)用(應(yīng)用版本 選擇 免費(fèi)開發(fā)版,key的類型 選擇 Web API)

創(chuàng)建成功后就可以看到 待會(huì)要用到的 key了

微信小程序后臺域名配置
登陸小程序后臺,分別點(diǎn)擊開發(fā)和開發(fā)設(shè)置

點(diǎn)擊修改,將我們要用到的 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小時(shí)預(yù)報(bào)</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天預(yù)報(bào)</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({
/**
* 頁面的初始數(shù)據(jù)
*/
data: {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面加載
*/
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: '為了給您提供準(zhǔn)確的天氣預(yù)報(bào)服務(wù),請?jiān)谠O(shè)置中授權(quán)【位置信息】',
success(mRes) {
if (mRes.confirm) {
wx.openSetting({
success: function (data) {
if (data.authSetting["scope.userLocation"] === true) {
that.selectLocation()
} else {
wx.showToast({
title: '授權(quán)失敗',
icon: 'none',
duration: 1000
})
}
}, fail(err) {
console.log(err)
wx.showToast({
title: '喚起設(shè)置頁失敗,請手動(dòng)打開',
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: '為了給您提供準(zhǔn)確的天氣預(yù)報(bào)服務(wù),請?jiān)谠O(shè)置中授權(quán)【位置信息】',
success(mRes) {
if (mRes.confirm) {
wx.openSetting({
success: function (data) {
if (data.authSetting["scope.userLocation"] === true) {
wx.showToast({
title: '授權(quán)成功',
icon: 'success',
duration: 1000
})
that.getLocation()
} else {
wx.showToast({
title: '授權(quán)失敗',
icon: 'none',
duration: 1000
})
that.setData({
location: "116.41,39.92"
})
that.getWeather()
that.getCityByLoaction()
}
}, fail(err) {
console.log(err)
wx.showToast({
title: '喚起設(shè)置頁失敗,請手動(dòng)打開',
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()
}
}
})
}
})
},
/**
* 根據(jù)坐標(biāo)獲取城市信息
*/
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()
}
})
},
// 格式時(shí)間
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()]
}
},
// 補(bǔ)零
formatNumber(n) {
n = n.toString()
return n[1] ? n : '0' + n
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面初次渲染完成
*/
onReady: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面顯示
*/
onShow: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面隱藏
*/
onHide: function () {
},
/**
* 生命周期函數(shù)--監(jiān)聽頁面卸載
*/
onUnload: function () {
},
/**
* 頁面相關(guān)事件處理函數(shù)--監(jiān)聽用戶下拉動(dòng)作
*/
onPullDownRefresh: function () {
},
/**
* 頁面上拉觸底事件的處理函數(shù)
*/
onReachBottom: function () {
},
/**
* 用戶點(diǎn)擊右上角分享
*/
onShareAppMessage: function () {
}
})
app.json
{
"pages": [
"pages/index/index"
],
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "天氣預(yù)報(bào)",
"navigationBarTextStyle": "black"
},
"permission": {
"scope.userLocation": {
"desc": "你的位置信息將用于天氣預(yù)報(bào)定位"
}
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
注意問題(必看)
為了確保 小程序 可以 正常使用,請先在和風(fēng)天氣 控制臺 升級為 個(gè)人開發(fā)者(ps:該升級需要上傳實(shí)名信息)。

在js代碼中,請將剛剛申請的key 填寫進(jìn) APIKEY 里面

源碼
Gitee源碼 (歡迎Start)
總結(jié)
到此這篇關(guān)于微信小程序天氣預(yù)報(bào)功能實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)微信小程序天氣預(yù)報(bào)功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mapboxgl區(qū)劃標(biāo)簽避讓不遮蓋實(shí)現(xiàn)的代碼詳解
Mapbox是一個(gè)可以免費(fèi)創(chuàng)建并定制個(gè)性化地圖的網(wǎng)站。這篇文章主要介紹了mapboxgl區(qū)劃標(biāo)簽避讓不遮蓋實(shí)現(xiàn)方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
javascript實(shí)現(xiàn)圖片上傳前臺頁面
這篇文章主要介紹使用javascript實(shí)現(xiàn)圖片上傳并在前臺頁面顯示,代碼很簡單,需要的朋友可以參考下2015-08-08
向大師們學(xué)習(xí)Javascript(視頻與PPT)
在開始之前,先與大家一起認(rèn)識下這篇文章的主角,世界級的javascript大牛們:Douglas Crockford、John Resig、Peter-Paul Koch、Nicolas C. Zakas??疵忠苍S挺陌生,但是如果你對javascript還算熟悉,一定不會(huì)對他們的作品陌生。2009-12-12
javascript 實(shí)現(xiàn)鍵盤上下左右功能的小例子
這篇文章介紹了javascript 實(shí)現(xiàn)鍵盤上下左右功能的小例子,有需要的朋友可以參考一下2013-09-09
JS中const對于復(fù)雜類型變量和普通類型變量的區(qū)別詳解
我們在開發(fā)的過程中一定常常發(fā)現(xiàn)const關(guān)鍵字定義的簡單類型變量不可以改變,但是你如果定義的是一個(gè)復(fù)雜類型變量(比如對象)的話對里面屬性的增刪改查是可以的,那這又是為什么呢,接下來就來和小編一起探討一下吧2023-11-11
node.js chat程序如何實(shí)現(xiàn)Ajax long-polling長鏈接刷新模式
node.js chat是node.js作者用JS寫的一個(gè)多人聊天工具, 源代碼公開下載,網(wǎng)址是chat.nodejs.org。作者用這個(gè)小例子,來展示如何用nodejs開發(fā)高效率的應(yīng)用程序。對于nodejs的學(xué)習(xí)者來說,是一個(gè)很好的例子2012-03-03

