微信小程序天氣預(yù)報功能實現(xiàn)(支持自動定位,附源碼)
前言
由于和風(fēng)天氣API的更新,之前寫的那篇文章 可能會出現(xiàn)版本不兼容的 情況。所以 更新了 這個 使用新版API的 小程序。
效果圖
天氣API獲取
這里我用的是和風(fēng)天氣的API,打開官網(wǎng)注冊或者登陸你的賬號
進(jìn)入控制臺,選擇應(yīng)用管理,新建應(yīng)用(應(yīng)用版本 選擇 免費開發(fā)版,key的類型 選擇 Web API)
創(chuàng)建成功后就可以看到 待會要用到的 key了
微信小程序后臺域名配置
登陸小程序后臺,分別點擊開發(fā)和開發(fā)設(shè)置
點擊修改,將我們要用到的 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小時預(yù)報</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ù)報</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ù)報服務(wù),請在設(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è)置頁失敗,請手動打開', 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ù)報服務(wù),請在設(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è)置頁失敗,請手動打開', 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() } }) }, // 格式時間 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)聽用戶下拉動作 */ onPullDownRefresh: function () { }, /** * 頁面上拉觸底事件的處理函數(shù) */ onReachBottom: function () { }, /** * 用戶點擊右上角分享 */ onShareAppMessage: function () { } })
app.json
{ "pages": [ "pages/index/index" ], "window": { "backgroundTextStyle": "light", "navigationBarBackgroundColor": "#fff", "navigationBarTitleText": "天氣預(yù)報", "navigationBarTextStyle": "black" }, "permission": { "scope.userLocation": { "desc": "你的位置信息將用于天氣預(yù)報定位" } }, "style": "v2", "sitemapLocation": "sitemap.json" }
注意問題(必看)
為了確保 小程序 可以 正常使用,請先在和風(fēng)天氣 控制臺 升級為 個人開發(fā)者(ps:該升級需要上傳實名信息)。
在js代碼中,請將剛剛申請的key 填寫進(jìn) APIKEY 里面
源碼
Gitee源碼 (歡迎Start)
總結(jié)
到此這篇關(guān)于微信小程序天氣預(yù)報功能實現(xiàn)的文章就介紹到這了,更多相關(guān)微信小程序天氣預(yù)報功能內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
CodeMirror實現(xiàn)代碼對比功能(插件react vue)
這篇文章主要介紹了CodeMirror實現(xiàn)代碼對比功能,用到的插件有vue或者react都需要這一步且同樣的下載方式,本文通過實例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05Avalon中文長字符截取、關(guān)鍵字符隱藏、自定義過濾器
avalon是一個簡單易用迷你的MVVM框架。通過本文給大家介紹Avalon中文長字符截取、關(guān)鍵字符隱藏、自定義過濾器的相關(guān)資料,需要的朋友一起學(xué)習(xí)吧2016-05-05JavaScript獲得頁面base標(biāo)簽中url的方法
這篇文章主要介紹了JavaScript獲得頁面base標(biāo)簽中url的方法,涉及javascript中元素的獲取及href屬性的使用技巧,需要的朋友可以參考下2015-04-04