如何在 Vue 3 + i18n 中导入多个语言环境 json 文件?
How to import multiple locale json files in Vue 3 + i18n?
这是我的代码,可以正常运行:
import { createI18n } from 'vue-i18n'
import messages from './components/json/foo/foo_messages.json'
const app = createApp(App)
installI18n(app)
const i18n = createI18n({
locale: 'ru',
messages
})
app
.use(i18n)
.use(vuetify)
.mount('#app')
现在我还需要加载来自 ./components/json/bar/bar_messages.json
的消息。我试过这样做:
import { createI18n } from 'vue-i18n'
import foo_msg from './components/json/foo/foo_messages.json'
import bar_msg from './components/json/bar/bar_messages.json'
const app = createApp(App)
installI18n(app)
const i18n = createI18n({
locale: 'ru',
messages: {foo_msg, bar_msg}
})
app
.use(i18n)
.use(vuetify)
.mount('#app')
但是没有用。谁能说说怎么做?
编辑:这是我的 foo json 文件
{
"ru": {
"header": {
"hello": "Привет"
}
},
"en": {
"header": {
"hello": "Hello"
}
}
}
这是酒吧 json 文件
{
"ru": {
"footer": {
"bye": "Пока"
}
},
"en": {
"footer": {
"bye": "Goodbye"
}
}
}
您尝试做的事情不是很可扩展。鉴于 i18n JSON 消息的格式,您需要将输入文件合并为如下格式:
{
"ru": {
"header": {
"hello": "Привет"
},
"footer": {
"bye": "Пока"
}
},
"en": {
"header": {
"hello": "Hello"
},
"footer": {
"bye": "Goodbye"
}
}
}
...这在 JS 中绝对可行,但您仍然必须为 main.js
中的每个组件导入 JSON 文件,这既乏味又容易出错
您是否考虑过在您的组件中使用 vue-i18n custom blocks?您甚至可以将翻译保留在外部 JSON 文件中,并使用像 <i18n src="./myLang.json"></i18n>
这样的自定义块
这是更好的方法,但如果您仍然想使用自己的方法,这里有一段简单的代码,说明如何将所有翻译文件(从 JSON 导入的对象)合并到 vue-i18n 可用的单个对象中:
// import foo_msg from './components/json/foo/foo_messages.json'
const foo_msg = {
"ru": {
"header": {
"hello": "Привет"
}
},
"en": {
"header": {
"hello": "Hello"
}
}
}
// import bar_msg from './components/json/bar/bar_messages.json'
const bar_msg = {
"ru": {
"footer": {
"bye": "Пока"
}
},
"en": {
"footer": {
"bye": "Goodbye"
}
}
}
const sources = [foo_msg, bar_msg]
const messages = sources.reduce((acc, source) => {
for(key in source) {
acc[key] = { ...(acc[key] || {}), ...source[key] }
}
return acc
},{})
console.log(messages)
接受的解决方案已经是很好的解决方案,但如果您协助使用.json文件来翻译文本。这是我的解决方案。
使用vue-cli添加i18n依赖,它会生成我们需要的所有需求文件。
vue add vue-i18n
它将在 src 中生成 locales 文件夹,其中存储所有翻译 json 文件。
然后它会在 .env 文件和一个 i18n.js 文件
上生成几个环境变量
这是它生成的i18n.js
import { createI18n } from 'vue-i18n'
/**
* Load locale messages
*
* The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
* See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
*/
function loadLocaleMessages() {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key).default
}
})
return messages
}
export default createI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})
在我们的main.js中,我看到vue已经帮我添加了组件
import i18n from './i18n'
const app = createApp(App).use(i18n)
*编辑
我正在使用 vite 构建 vue 项目,loadLocaleMessages
在我的情况下不起作用。
我做了一些修改。它需要手动导入所有 json 文件,但我没有找到任何替代解决方案。
我还更改了带有 'VITE' 前缀的 env 变量,并将 process.env 更改为 import.meta.env。
// import all the json files
import en from './locales/en.json'
import zh from './locales/zh.json'
/**
* Load locale messages
*
* The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
* See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
*/
function loadLocaleMessages() {
const locales = [{ en: en }, { zh: zh }]
const messages = {}
locales.forEach(lang => {
const key = Object.keys(lang)
messages[key] = lang[key]
})
return messages
}
export default createI18n({
locale: import.meta.env.VITE_APP_I18N_LOCALE || 'en',
fallbackLocale: import.meta.env.VITE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})
这是我的代码,可以正常运行:
import { createI18n } from 'vue-i18n'
import messages from './components/json/foo/foo_messages.json'
const app = createApp(App)
installI18n(app)
const i18n = createI18n({
locale: 'ru',
messages
})
app
.use(i18n)
.use(vuetify)
.mount('#app')
现在我还需要加载来自 ./components/json/bar/bar_messages.json
的消息。我试过这样做:
import { createI18n } from 'vue-i18n'
import foo_msg from './components/json/foo/foo_messages.json'
import bar_msg from './components/json/bar/bar_messages.json'
const app = createApp(App)
installI18n(app)
const i18n = createI18n({
locale: 'ru',
messages: {foo_msg, bar_msg}
})
app
.use(i18n)
.use(vuetify)
.mount('#app')
但是没有用。谁能说说怎么做?
编辑:这是我的 foo json 文件
{
"ru": {
"header": {
"hello": "Привет"
}
},
"en": {
"header": {
"hello": "Hello"
}
}
}
这是酒吧 json 文件
{
"ru": {
"footer": {
"bye": "Пока"
}
},
"en": {
"footer": {
"bye": "Goodbye"
}
}
}
您尝试做的事情不是很可扩展。鉴于 i18n JSON 消息的格式,您需要将输入文件合并为如下格式:
{
"ru": {
"header": {
"hello": "Привет"
},
"footer": {
"bye": "Пока"
}
},
"en": {
"header": {
"hello": "Hello"
},
"footer": {
"bye": "Goodbye"
}
}
}
...这在 JS 中绝对可行,但您仍然必须为 main.js
中的每个组件导入 JSON 文件,这既乏味又容易出错
您是否考虑过在您的组件中使用 vue-i18n custom blocks?您甚至可以将翻译保留在外部 JSON 文件中,并使用像 <i18n src="./myLang.json"></i18n>
这是更好的方法,但如果您仍然想使用自己的方法,这里有一段简单的代码,说明如何将所有翻译文件(从 JSON 导入的对象)合并到 vue-i18n 可用的单个对象中:
// import foo_msg from './components/json/foo/foo_messages.json'
const foo_msg = {
"ru": {
"header": {
"hello": "Привет"
}
},
"en": {
"header": {
"hello": "Hello"
}
}
}
// import bar_msg from './components/json/bar/bar_messages.json'
const bar_msg = {
"ru": {
"footer": {
"bye": "Пока"
}
},
"en": {
"footer": {
"bye": "Goodbye"
}
}
}
const sources = [foo_msg, bar_msg]
const messages = sources.reduce((acc, source) => {
for(key in source) {
acc[key] = { ...(acc[key] || {}), ...source[key] }
}
return acc
},{})
console.log(messages)
接受的解决方案已经是很好的解决方案,但如果您协助使用.json文件来翻译文本。这是我的解决方案。
使用vue-cli添加i18n依赖,它会生成我们需要的所有需求文件。
vue add vue-i18n
它将在 src 中生成 locales 文件夹,其中存储所有翻译 json 文件。 然后它会在 .env 文件和一个 i18n.js 文件
上生成几个环境变量这是它生成的i18n.js
import { createI18n } from 'vue-i18n'
/**
* Load locale messages
*
* The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
* See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
*/
function loadLocaleMessages() {
const locales = require.context('./locales', true, /[A-Za-z0-9-_,\s]+\.json$/i)
const messages = {}
locales.keys().forEach(key => {
const matched = key.match(/([A-Za-z0-9-_]+)\./i)
if (matched && matched.length > 1) {
const locale = matched[1]
messages[locale] = locales(key).default
}
})
return messages
}
export default createI18n({
locale: process.env.VUE_APP_I18N_LOCALE || 'en',
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})
在我们的main.js中,我看到vue已经帮我添加了组件
import i18n from './i18n'
const app = createApp(App).use(i18n)
*编辑
我正在使用 vite 构建 vue 项目,loadLocaleMessages
在我的情况下不起作用。
我做了一些修改。它需要手动导入所有 json 文件,但我没有找到任何替代解决方案。
我还更改了带有 'VITE' 前缀的 env 变量,并将 process.env 更改为 import.meta.env。
// import all the json files
import en from './locales/en.json'
import zh from './locales/zh.json'
/**
* Load locale messages
*
* The loaded `JSON` locale messages is pre-compiled by `@intlify/vue-i18n-loader`, which is integrated into `vue-cli-plugin-i18n`.
* See: https://github.com/intlify/vue-i18n-loader#rocket-i18n-resource-pre-compilation
*/
function loadLocaleMessages() {
const locales = [{ en: en }, { zh: zh }]
const messages = {}
locales.forEach(lang => {
const key = Object.keys(lang)
messages[key] = lang[key]
})
return messages
}
export default createI18n({
locale: import.meta.env.VITE_APP_I18N_LOCALE || 'en',
fallbackLocale: import.meta.env.VITE_APP_I18N_FALLBACK_LOCALE || 'en',
messages: loadLocaleMessages()
})