项目需求
最近做了一个小程序,首页中头部需要展示当前定位和天气相关信息,第一时间相到去找官方的组件,然后又去找别人分享的组件,可能是我打开的方式不对,搜寻未果,只好自己写了一个,分享一下,仅供参考
使用方法
直接copy下放代码,在需要的地方直接使用标签引入即可
<!-- 其他页面代码 -->
<!-- 天气定位 -->
<weather></weather>
<!-- 其他页面代码 -->
当然使用之前要先导入
import { weather } from "@/components/weather";
先看效果:

组件完整代码:
<!-- 天气组件 -->
<template>
<view class="weather_wrap">
<!-- 天气 -->
<view class="weather">
<image :src="weather_icon" mode="widthFix"></image>
<text>{{ weather_text }}</text>
</view>
<!-- 定位 -->
<view class="site">
<text class="iconfont icon-weizhi"></text>
<text>{{ city || "定位失败" }}</text>
</view>
<!-- 温度、空气质量等详细信息 -->
<view class="weather_detail">
<view class="wether_detail_item">
<text class="detail_item_data">{{ temp }}℃</text>
<text class="detail_item_title">室外温度</text>
</view>
<view class="wether_detail_item">
<text class="detail_item_data">{{p2m5}}</text>
<text class="detail_item_title">室外PM2.5</text>
</view>
<view class="wether_detail_item">
<text class="detail_item_data">{{air_text}}</text>
<text class="detail_item_title">室外空气质量</text>
</view>
</view>
</view>
</template>
<script>
import qqmapsdk from "../utils/qqmap-wx-jssdk.min";
export default {
data() {
//这里存放数据
return {
temp: 0,
latitude: 0,
longitude: 0,
city: "",
weather_text: "",
weather_icon:"",
weather_icon_head: "/static/weather/WeatherIcon/weather-icon-S2/64/",
air_text:"",
p2m5:""
// weather_icon: "/static/weather/WeatherIcon/weather-icon-S2/64/101.png",
};
},
methods: {
getUserPosition() {
/**
* 在这里执行获取用户的位置
*/
//获取用户位置
let that = this;
uni.getLocation({
type: "wgs84",
geocode: true,
success: (res) => {
console.log("获取经纬度成功", res);
let lo = res.longitude;
let la = res.latitude;
that.latitude = la;
that.longitude = lo;
this.getWeatherInfo(lo, la);
this.getCity(lo, la);
this.getAir(lo, la);
},
});
},
getCity(lo, la) {
const QQMapWX = new qqmapsdk({
//腾讯地图key
key: this.thirdKeys.keysObj.txMapKey,
});
let that = this;
QQMapWX.reverseGeocoder({
location: {
latitude: la,
longitude: lo,
},
success: function (res) {
console.log("解析地址成功", res);
that.city = " " + res.result.address_component.city.replace("市","")
},
fail: function (res) {
console.log(res);
},
complete: function (res) {
console.log(res);
},
});
},
getWeatherInfo() {
let lo = this.longitude;
let la = this.latitude;
let hfKey = this.thirdKeys.keysObj.hfKey;
let that = this;
wx.request({
url:
"https://devapi.qweather.com/v7/weather/now?location=" +
lo +
"," +
la +
"&key=" +
hfKey,
method: "get",
success(res) {
console.log("weRes", res);
that.weather_text = res.data.now.text;
that.weather_icon =
that.weather_icon_head + res.data.now.icon + ".png";
that.temp = res.data.now.temp;
},
fail(err) {
console.log("weErr", err);
},
});
},
getAir() {
let lo = this.longitude;
let la = this.latitude;
let hfKey = this.thirdKeys.keysObj.hfKey;
let that = this;
wx.request({
url:
"https://devapi.qweather.com/v7/air/now?location=" +
lo +
"," +
la +
"&key=" +
hfKey,
method: "get",
success(res) {
console.log("airRes", res);
that.air_text = res.data.now.category;
that.p2m5 = that.getPM25(res.data.now.pm2p5);
},
fail(err) {
console.log("weErr", err);
},
});
},
getPM25(v) {
if (v > 0 && v < 35) {
return "优";
} else if (v >= 35 && v < 75) {
return "良";
} else if (v >= 75 && v < 115) {
return "轻度污染";
} else if (v >= 115 && v < 150) {
return "中度污染";
} else if (v >= 150 && v < 250) {
return "重度污染";
} else if (v >= 250) {
return "严重污染";
}
},
},
mounted() {
console.log("天气组件挂载...");
this.getUserPosition();
},
};
</script>
<style lang="scss">
.weather_wrap {
border-radius: 0 0 20rpx 20rpx;
margin-bottom: 40rpx;
padding-top: 50rpx;
background-color: #fff;
.weather {
display: flex;
justify-content: center;
image {
width: 90rpx;
height: 90rpx;
margin-right: 10rpx;
}
text {
font-weight: 600;
font-size: 50rpx;
line-height: 90rpx;
}
}
.site {
width: 200rpx;
height: 70rpx;
border: 1px solid #b9b9b9;
border-radius: 35rpx;
margin: 30rpx auto;
text-align: center;
line-height: 70rpx;
font-size: 32rpx;
.iconfont {
font-weight: 600;
line-height: 70rpx;
font-size: 32rpx;
}
}
.weather_detail {
width: 85%;
height: 100rpx;
display: flex;
margin: 10rpx auto;
.wether_detail_item {
flex: 1;
display: flex;
flex-direction: column;
text-align: center;
.detail_item_data {
font-weight: 600;
font-size: 35rpx;
}
.detail_item_title {
color: #b9b9b9;
}
}
}
}
</style>