首次打开显示默认城市-广州(可自定义)的天气
点击获取当前位置(首次打开),跳出弹框请求授权
非首次打开(已授权)则直接显示本地的天气信息,并将当前位置存入本地缓存,下次打开小程序直接显示本地的天气信息
头部(top)城市天气搜索框和获取当前位置的组件
中部(body)天气的显示
底部(bottom)未来天气的显示
完整代码在文章后面提供
需要先去百度开放平台申请密钥ak // 百度ak申请方法:点击此处跳转查看
小程序的内置接口只能获取到经纬度信息,无法直接获取位置信息,需要通过调用百度地图提供的接口解析成位置信息
存数据
取数据
(在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"
}