Vue3切换语言时重新请求OpenWeatherMap API更新天气描述
问题:切换应用语言时OpenWeatherMap天气描述无法更新
我是一名Vue3初学者,正在基于OpenWeatherMap API开发简易天气网页应用。使用vue-i18n库实现多语言支持后,其他功能正常,但OpenWeatherMap(OWM)API返回的天气描述语言取决于请求的lang参数,切换应用语言时天气描述无法更新,需用正确lang值重新请求API,却不知如何实现。请问如何重新渲染组件以获取对应语言的天气描述?
组件相关代码
<script setup> import axios from "axios"; import { useRoute, useRouter } from 'vue-router'; import { useI18n } from "vue-i18n"; const { t } = useI18n(); const i18nLocale = useI18n(); const route = useRoute(); const getWeatherData = async () => { const langapi = i18nLocale.locale.value.substring(0, 2); try { const weatherData = await axios.get(`https://api.openweathermap.org/data/3.0/onecall?lat=${route.query.lat}&lon=${route.query.lng}&exclude={part}&appid=${myapikey}&units=metric&lang=${langapi}`); // cal current date & time const localOffset = new Date().getTimezoneOffset() * 60000; const utc = weatherData.data.current.dt * 1000 + localOffset; weatherData.data.currentTime = utc + 1000 * weatherData.data.timezone_offset; // cal hourly weather offset weatherData.data.hourly.forEach((hour) => { const utc = hour.dt * 1000 + localOffset; hour.currentTime = utc + 1000 * weatherData.data.timezone_offset; }); await new Promise((res) => setTimeout(res, 500)); return weatherData.data; } catch (error) { console.log(error); } } const weatherData = await getWeatherData(); // ... </script> <template> // ... <p class="capitalize"> {{ weatherData.current.weather[0].description }} </p> // ... </template>
我猜测需刷新组件重新调用API,或直接重新调用getWeatherData函数,但不知具体操作方法。
解决方案
不用刷新组件,只需监听语言变化并重新调用API更新数据即可,具体修改步骤如下:
1. 将weatherData改为响应式变量
原来的一次性赋值无法触发视图更新,需要用ref包装成响应式变量:
import { ref } from 'vue'; // 初始化响应式变量,先设为null const weatherData = ref(null);
2. 重构数据加载函数
修改getWeatherData为直接更新响应式变量的函数,方便重复调用:
const loadWeatherData = async () => { const langapi = i18nLocale.locale.value.substring(0, 2); try { const response = await axios.get(`https://api.openweathermap.org/data/3.0/onecall?lat=${route.query.lat}&lon=${route.query.lng}&exclude={part}&appid=${myapikey}&units=metric&lang=${langapi}`); // 保留原有日期时间处理逻辑 const localOffset = new Date().getTimezoneOffset() * 60000; const utc = response.data.current.dt * 1000 + localOffset; response.data.currentTime = utc + 1000 * response.data.timezone_offset; response.data.hourly.forEach((hour) => { const utc = hour.dt * 1000 + localOffset; hour.currentTime = utc + 1000 * response.data.timezone_offset; }); await new Promise((res) => setTimeout(res, 500)); // 更新响应式变量,触发视图刷新 weatherData.value = response.data; } catch (error) { console.log(error); } }
3. 初始化加载数据
组件挂载时调用一次加载函数:
// 组件初始化时加载初始数据 await loadWeatherData();
4. 监听语言变化自动刷新数据
使用watch监听vue-i18n的locale值,一旦语言切换就重新请求API:
import { watch } from 'vue'; // 监听语言切换事件 watch( () => i18nLocale.locale.value, () => { // 语言变化时重新加载天气数据 loadWeatherData(); }, { immediate: false } // 初始化不重复调用,避免重复请求 );
5. 模板处理空值避免报错
因为weatherData初始为null,模板中需要添加判断:
<template> <!-- ... --> <p class="capitalize" v-if="weatherData"> {{ weatherData.current.weather[0].description }} </p> <p v-else>加载中...</p> <!-- ... --> </template>
内容的提问来源于stack exchange,提问作者feub
相关产品推荐
相关产品推荐

