Vue.js + i18n 从服务器加载外部 JSON 并使其在每个组件中都可以全局访问

Vue.js + i18n load external JSON's from server and make it globally accessible in every component

我目前正在尝试找到一种从服务器加载翻译文件并使它们在项目的每个组件中都可访问的方法。

例如,我可以调用 https://server.com/lang=de 并得到 JSON

{
    "DASHBOARD_SETTINGS": "Einstellungen",
    "DASHBOARD_CUSTOMERS": "Kunden",
    "DASHBOARD_CAMPAIGNS": "Kampagnen",
    "DASHBOARD_LOCATIONS": "Standorte",
    "DASHBOARD_DISPLAYS": "Displays"
}

这是我的文件结构

i18n_setup.js

import Vue from 'vue'
import VueI18n from 'vue-i18n'

Vue.use(VueI18n)

export const i18n = new VueI18n({
    locale: 'de',
    fallbackLocale: 'en'
})

const loadedLanguages = ['de']

function setI18nLanguage (lang) {
    i18n.locale = lang
    axios.defaults.headers.common['Accept-Language'] = lang
    document.querySelector('html').setAttribute('lang', lang)
    return lang
}

export function loadLanguageAsync (lang) {
    if (typeof lang === 'undefined') {
        lang = window.navigator.userLanguage || window.navigator.language;
        lang = lang.slice(0,2);
    }
    if (loadedLanguages.includes(lang)) {
        if (i18n.locale !== lang) setI18nLanguage(lang)
        return Promise.resolve()
    }
    return fetch(`https://EXAMPLE.de/locales?lang=${lang}`)
        .then(response => {
            let msgs = response.data
            loadedLanguages.push(lang)
            i18n.setLocaleMessage(lang, msgs)
            return setI18nLanguage(lang)
        });
}

router.js

...
router.beforeEach((to, from, next) => {
    const lang = to.params.lang
    loadLanguageAsync(lang).then(() => next())
})

app.js

...
// i18n
import { i18n } from './i18n_setup'
...
const app = new Vue({
    store,
    i18n,
    el: '#app',
    components: {
        App
    },
    router
});

Dashboard.vue

import { loadLanguageAsync } from '../i18n_setup'

我可以看到翻译是通过浏览器的网络选项卡加载的,但是当我尝试使用例如 {{ $t('DASHBOARD_SETTINGS') }} 访问翻译时 我收到警告/错误

[vue-i18n] Cannot translate the value of keypath 'DASHBOARD_SETTINGS'. Use the value of keypath as default.

知道我遗漏了什么吗?

fetch returns Response 类型的对象。您正在访问该对象 (let msgs = response.data)

上不存在的 response.data

要从响应中提取数据,请使用 response.json()

return fetch(`https://EXAMPLE.de/locales?lang=${lang}`)
  .then(response => response.json())
  .then(msgs => {
     loadedLanguages.push(lang)
     i18n.setLocaleMessage(lang, msgs)
     return setI18nLanguage(lang)
   });