You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:23:10