场景介绍
「天气预报」功能在一些后台管理系统中,也是一些常见的需求,本文介绍一下如何在我们的vue项目中加入此功能
用到的一些API和库
- axios用于request请求
- 高德地图IP定位
- 高德地图天气查询
- 天气对照表
- vue-skycons用于展示天气动画的icon
需求拆解
我们的需求是获取本地的天气,从代码角度,我们进行拆分
第一步,获取到当前用户的位置
因为项目中用的高德地图API较多,所以使用高德地图IP定位来获取当前位置
注:使用高德地图需要申请对应key值,详见lbs.amap.com/api/webserv…
如果你没有申请,可以先用小在的key值6b3fbbe2ba9360bd1290adfe7d29a449
我们在网页中直接调用restapi.amap.com/v3/ip?key=6…测试一下
这里我们已经获取到了当前的定位,需要将adcode记录下来,第二步时会用到
第二步,通过位置查询对应的天气
我们同样使用高德的免费API,高德地图天气查询
我们在网页中直接调用restapi.amap.com/v3/weather/…测试一下,city的值是第一步获取的adcode,我们得到以下信息
第三步,将获取到的天气数据,渲染到我们的页面中
因为高德返回的天气是中文,我们需要根据官方提供的天气对照表来展示不同的icon,这里我们使用vue-skycons作为我们的icon库,根据不同的天气,展示不同的动画icon
具体代码
1.安装依赖
npm i axios
npm i vue-skycon
2.新建LocalWeather.vue文件
<!-- 获取当地天气 -->
<template>
<div class="flex-center">
<skycon v-if="iconCondition" :condition="iconCondition" color="white" size="40" />
<div v-if="iconCondition" class="flex-center font-22">
<span>{{ weather.temperature }}℃ </span>
<span>{{ weather.weather }}</span>
</div>
</div>
</template>
<script>
import axios from 'axios';
import Skycon from 'vue-skycons';
export default {
components: { Skycon },
data() {
return {
key: '6b3fbbe2ba9360bd1290adfe7d29a449', //小在自己的key,建议自己申请
weather: {}, //用于存放天气相关的数据
iconCondition: null, //icon值
};
},
created() {
this.getLocationInfo();
},
methods: {
// 获取用户位置信息
async getLocationInfo() {
const params = {
key: this.key,
};
const { data } = await axios.get('https://restapi.amap.com/v3/ip', { params });
// data.adcode值为获取天气需要的city值
this.getWeather(data.adcode);
},
// 获取天气详情
async getWeather(adcode) {
const params = {
key: this.key,
city: adcode,
};
const { data } = await axios.get(`https://restapi.amap.com/v3/weather/weatherInfo`, { params });
this.weather = data.lives[0];
this.iconCondition = this.setWeatherIcon(data.lives[0]?.weather);
},
// 设置icon
setWeatherIcon(weather) {
// 只处理了基础的天气,可以继续精细化处理
if (weather === '晴') {
return 'clear-day';
} else if (weather.includes('云')) {
return 'partly-cloudy-day';
} else if (weather.includes('风')) {
return 'wind';
} else if (weather.includes('雨')) {
return 'rain';
} else if (weather.includes('雪')) {
return 'snow';
} else if (weather.includes('雾')) {
return 'fog';
}
return 'cloudy';
},
},
};
</script>
<style lang="less" scoped>
.flex-center {
display: flex;
justify-content: center;
align-items: center;
}
.font-22 {
font-size: 22px;
}
</style>