使用weather api以及vue3实现一个天气组件

发布于:2024-10-08 ⋅ 阅读:(176) ⋅ 点赞:(0)

一、前言

之前使用国内的和风天气实现了一个天气组件,但是后来发现,对于海外地址,和风天气常常没有对应的天气信息,对国外用户来说并不友好,于是我开始寻找国外好用的天气api,终于发现了一个名字就叫weather api的产品[破涕为笑]。
官网:weather api
官方文档:https://www.weatherapi.com/docs/

二、注意事项及优点

为什么把优点及注意事项放在此处,是因为该产品如果想要获得良好的体验,是需要付费的(当然,天气api产品几乎都需要收费才能提供更多的天气数据,并且国外产品收费更普遍),那为什么选择它呢?

1、价格相较于国外使用率高的天气api更便宜(当然,免费版也能展示基本数据)

对比了open weather等几个国外知名的天气api,它的收费档位相对来说便宜很多。并且对于初次注册的用户,赠送了14天的免费使用。
收费档位

2、仅需一个接口就能获取到需要的大部分数据

抛开获取位置信息的接口,weather api一个接口就能获取到当前天气、小时天气、未来天气预报、空气质量等众多信息,大大减少了请求量(大部分api产品都是限制了每月请求次数的)。

三、使用

1、注册获取api key

首先进入官网sigh up注册后会进入个人页面,在此可以获取api key,这是能够使用weather api的关键:
个人页面

2、使用(以获取当前天气、空气质量、小时天气、未来天气为例)

请求拦截器:
// /utils/axiosUtils.js
import axios from 'axios';

const axiosInstance = axios.create({
    baseURL: 'https://api.weatherapi.com/v1',
    timeout: 5000
});

// 请求拦截器
axiosInstance.interceptors.request.use(
    (config) => {
        config.params.lang = 'en'
        if(config.method === 'get' && !config.params.key){
            config.params.key = xxxx(此处填写你的api key)
        }
        return config;
    },
    (error) => {
        return Promise.reject(error);
    }
);

// 响应拦截器
axiosInstance.interceptors.response.use(
(response) => {
    return {
        code: response.status,
        ...response.data
    }
},
(error) => {
    console.error('error', error);
    return Promise.reject(error);
}
);

export default axiosInstance;
api方法:
// /api/weather.js
import axiosInstance from '../utils/axiosUtils'

// 城市搜索(还是用的以前和风天气的,自己可以换成weather api的接口)
export function getCityInfo (params) {
    return axiosInstance({
        baseURL: 'https://geoapi.qweather.com',
        url: '/v2/city/lookup',
        params: {
            ...params,
            key: import.meta.env.VITE_WEATHER_LOCATION_APP_ID
        },
        method: 'get'
    })
}

export function getWeatherInfo (params) {
    return axiosInstance({
        url: '/forecast.json',
        params:{
            ...params,
            days: 8, // 获取未来8天天气预报
            hours: 24, // 获取未来多少个小时天气
            aqi: 'yes', // 是否获取空气质量
            alerts: 'no' // 禁用警告
            // 以上参数可以在调用方法时再传
        },
        method: 'get'
    })
}
获取数据
// index.vue
<script setup lang="ts">
import { reactive } from "vue"
import {
    getCityInfo,
    getWeatherInfo,
} from './api/weather.js'

const data:any = reactive({
    city: {}, // 当前城市
    weather: {}, // 当前天气
    hourWeather: [], // 逐小时天气
    forecast: [] as any, // 天气预报
    location: '',
    formattedDate: '',
    loaded: 0 // 加载状态(0:加载中,1:加载完成,2:错误)
})

// 获取坐标信息(参数为地理坐标或城市名,不传参就是当前位置查询)
const getLocation = async (query?: string) => {
    if (query) {
        // 用于搜索
        getCity(query)
    } else {
        if ('geolocation' in navigator) {
            navigator.geolocation.getCurrentPosition(pos => {
                const {latitude, longitude} = pos.coords
                data.location = `${longitude},${latitude}`
                getCity(data.location)
            },
            err => {
                alert('Failed to obtain location.')
            })
        } else  {
            alert('Could not get location.')
        }
    }
}

const getCity = async (query) => {
    // 获取城市信息
    const cityRes:any = await getCityInfo({location: query})
    weatherInfo(cityRes.location[0] || {})
}

// 根据城市信息获取天气信息
const weatherInfo = (cityInfo) => {
    data.city = cityInfo
    const { lon, lat } = cityInfo
    const location = `${lat},${lon}`
    getWeatherInfo({q:location}).then((res:any)=>{
        if(res.code == 200){
			data.weather = res.current
	        data.hourWeather = res.forecast.forecastday[0]?.hour
	        data.forecast = res.forecast.forecastday
	        data.formattedDate = data.weather.last_updated
	        data.loaded = 1
		}else{
			data.loaded = 2
		}
    })
}
</script>

通过以上数据,就能实现数据展示啦,各字段名代表什么需要自己去官方文档查看哦。