vue项目中嵌入「天气预报」功能

2,537 阅读2分钟

场景介绍

image-20221116165644539.png

「天气预报」功能在一些后台管理系统中,也是一些常见的需求,本文介绍一下如何在我们的vue项目中加入此功能

用到的一些API和库

  1. axios用于request请求
  2. 高德地图IP定位
  3. 高德地图天气查询
  4. 天气对照表
  5. vue-skycons用于展示天气动画的icon

需求拆解

我们的需求是获取本地的天气,从代码角度,我们进行拆分

第一步,获取到当前用户的位置

因为项目中用的高德地图API较多,所以使用高德地图IP定位来获取当前位置

注:使用高德地图需要申请对应key值,详见lbs.amap.com/api/webserv…

如果你没有申请,可以先用小在的key值6b3fbbe2ba9360bd1290adfe7d29a449

image-20221116171331479.png 我们在网页中直接调用restapi.amap.com/v3/ip?key=6…测试一下

image-20221116171723803.png 这里我们已经获取到了当前的定位,需要将adcode记录下来,第二步时会用到

第二步,通过位置查询对应的天气

我们同样使用高德的免费API,高德地图天气查询 image-20221116171939159.png image-20221116171948573.png

我们在网页中直接调用restapi.amap.com/v3/weather/…测试一下,city的值是第一步获取的adcode,我们得到以下信息

image-20221116172148041.png

第三步,将获取到的天气数据,渲染到我们的页面中

因为高德返回的天气是中文,我们需要根据官方提供的天气对照表来展示不同的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>
3.在需要的地方引用LocalWeather.vue