Nuxt3 i18n切换Locale未调用后端API及首屏数据加载问题
解决方案:切换Locale触发API请求并实现首屏公共数据加载
1. 修复API请求的响应式Locale头部与缓存隔离
当前useApi中locale为静态取值,无法随语言切换更新请求头,且请求key未关联locale,导致不同语言下同一接口复用缓存。修改如下:
import { defu, toValue } from 'defu' import { useI18n } from 'vue-i18n' export const useApi = (url, options = {}) => { const config = useRuntimeConfig() const { locale } = useI18n() // 获取响应式locale对象 const defaults = { baseURL: config.public.apiBase, // 将locale加入请求key,确保不同语言的请求缓存独立 key: `${toValue(url)}_${locale.value}`, // 用computed实现请求头随locale自动更新 headers: computed(() => ({ 'Locale': locale.value })) } const params = defu(options, defaults) return useFetch(url, params) }
2. 实现菜单数据随Locale切换自动重载
当前app.vue中的useAsyncData仅初始化执行一次,未监听locale变化。修改为响应式触发:
<script setup> import { useI18n } from 'vue-i18n' import { useMenus } from './stores/menus' import { useHead } from '#imports' const { locale } = useI18n() const menusStore = useMenus() // 监听locale变化,自动重新拉取对应语言的菜单 const { data: menusData } = useAsyncData( () => `menus_${locale.value}`, // 动态key避免缓存冲突 () => menusStore.asyncData(locale.value), { watch: [locale] } // 绑定locale为监听源,变化时触发请求 ) useHead({ htmlAttrs: { lang: locale.value } }) </script>
3. 保障公共数据首屏加载优先级
- 将菜单、底部这类公共数据的请求放在
app.vue或全局布局组件(如layouts/default.vue)中,确保页面渲染前优先完成数据加载。 - 配合Pinia存储数据时,在store的异步方法中调用修改后的
useApi:
示例(stores/menus.js):
import { defineStore } from 'pinia' import { useApi } from '@/composables/useApi' export const useMenus = defineStore('menus', { state: () => ({ data: null }), actions: { async asyncData() { const { data } = await useApi('/api/menus') this.data = data.value return data.value } } })
4. 确认Locale导航配置正确性
确保nuxt.config.ts中的i18n配置与你的路由逻辑匹配:
export default defineNuxtConfig({ modules: ['@nuxtjs/i18n'], i18n: { locales: [ { code: 'tr', iso: 'tr-TR' }, { code: 'en', iso: 'en-US' }, { code: 'ru', iso: 'ru-RU' } ], defaultLocale: 'tr', strategy: 'prefix_except_default' // 对应logoLink的路由逻辑 } })
完成以上修改后,切换语言时nuxt-link会导航到对应语言的URL,同时useAsyncData会因locale变化触发重新请求,useApi自动携带最新的Locale请求头,实现语言切换时的数据同步更新,且公共数据会在首屏优先加载。
内容的提问来源于stack exchange,提问作者İrem Turgut
相关产品推荐
相关产品推荐

