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"
}
这是我的文件结构
- router.js
- i18n_setup.js
- app.js
- 组件
- Dashboard.vue
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)
});
我目前正在尝试找到一种从服务器加载翻译文件并使它们在项目的每个组件中都可访问的方法。
例如,我可以调用 https://server.com/lang=de 并得到 JSON
{
"DASHBOARD_SETTINGS": "Einstellungen",
"DASHBOARD_CUSTOMERS": "Kunden",
"DASHBOARD_CAMPAIGNS": "Kampagnen",
"DASHBOARD_LOCATIONS": "Standorte",
"DASHBOARD_DISPLAYS": "Displays"
}
这是我的文件结构
- router.js
- i18n_setup.js
- app.js
- 组件
- Dashboard.vue
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)
});