29 多语言配置 - udo-bit/naive_admin_pro GitHub Wiki
完成全局多语言配置
我们在开发的过程中避免不了会有使用多语言的情况,那么接下来我们就一起配置一下多语言的功能。
在src目录下创建一个locales的文件夹,用于存放我们的多语言。再创建一个index.ts作为我们多语言的出口。
import { createI18n } from 'vue-i18n'
export const defaultLocale = 'zh-CN'
const i18n = createI18n({
// 是否启用传统模式,默认true,我们这里新项目我们不需要
legacy: false,
// 本地化语言获取失败的时候是否输出警告
missingWarn: false,
// 默认多语言
locale: defaultLocale,
messages: {
},
})
export default i18n
在main.ts中进行导出我们的多语言:
import i18n from '~/locales'
app.use(i18n)
接下来我们来配置一下naiveui的默认多语言,我们先在locales下面创建一个lang的文件夹,用于存放我们的多语言部分。我们以中英文为例子,如果您还需要其他的多语言请自行添加配置。 接下来我们在lang中添加多语言文件分别为:en-US.ts何zh-CN.ts文件 en-US.ts
import { dateEnUS, enUS } from 'naive-ui'
export default {
naiveUI: {
locale: enUS,
dateLocale: dateEnUS,
},
}
zh-CN.ts
import { dateZhCN, zhCN } from 'naive-ui'
export default {
naiveUI: {
locale: zhCN,
dateLocale: dateZhCN,
},
}
然后在locales/index.ts中导入
import { createI18n } from 'vue-i18n'
import zhCN from '~/locales/lang/zh-CN'
export const defaultLocale = 'zh-CN'
const i18n = createI18n({
// 是否启用传统模式,默认true,我们这里新项目我们不需要
legacy: false,
// 本地化语言获取失败的时候是否输出警告
missingWarn: false,
// 默认多语言
locale: defaultLocale,
messages: {
'zh-CN': zhCN,
},
})
export default i18n
然后我们创建一个组合式的api用于处理我们的多语言,在composables下创建一个auto-lang.ts的文件
import i18n, { defaultLocale } from '~/locales'
export const useAppLocale = createGlobalState(() => useStorage('locale', defaultLocale))
export const useAutoLang = () => {
const appLocale = useAppLocale()
const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI)
return {
targetLocale,
}
}
然后在App.vue中使用
<script setup lang="ts">
const appStore = useAppStore()
const { layoutTheme, overridesTheme } = storeToRefs(appStore)
useAutoDark()
+ const { targetLocale } = useAutoLang()
</script>
<template>
<n-config-provider
+ :locale="targetLocale.locale"
+ :date-locale="targetLocale.dateLocale"
:theme="layoutTheme"
:theme-overrides="overridesTheme"
>
<n-global-style />
<app-provider>
<router-view />
</app-provider>
</n-config-provider>
</template>
然后我们发现控制台会报如下的警告:
本身我们是需要使用esm的方式去构建的,所以我们在vite.config.ts中做如下的配置:
export default defineConfig({
define: {
__VUE_I18N_FULL_INSTALL__: false,
__VUE_I18N_LEGACY_API__: false,
},
})
然后我们重启项目,发现我们的报错就没有了。
一次性加载所有的多语言是多余且没有必要的,所以接下来我们来实现一下动态加载我们的多语言的功能。 官方也提供了一个动态加载的例子lazy loading 我们在locales/index.ts中增加如下代码:
export const loadLanguageAsync = async (lang: string = defaultLocale) => {
const current = i18n.global.locale.value
if (current !== lang) {
const messages = await import(`./lang/${lang}.ts`)
i18n.global.setLocaleMessage(lang, messages.default)
}
return nextTick()
}
然后我们在auto-lang中实现设置多语言。 首先我们可以先获取我们当前的系统语言,如果当前系统语言是其他语言那么我们默认加载其他的语言。 获取当前系统的语言我们可以通过vueuse中的useNavigatorLanguage的组合式api进行获取,实现代码如下:
import i18n, { defaultLocale, loadLanguageAsync } from '~/locales'
export const useAppLocale = createGlobalState(() => useStorage('locale', defaultLocale))
export const useAutoLang = () => {
const appLocale = useAppLocale()
const { isSupported, language } = useNavigatorLanguage()
const setLanguage = async (lang: string) => {
try {
await loadLanguageAsync(lang)
appLocale.value = lang
}
catch (e) {
throw new Error(`Failed to load language: ${lang}`)
}
}
if (isSupported.value) {
if (language.value !== defaultLocale)
setLanguage(language.value!).then(() => {})
watch(language, () => {
setLanguage(language.value!).then(() => {})
})
}
else {
if (appLocale.value !== defaultLocale)
setLanguage(appLocale.value).then(() => {})
}
watch(appLocale, () => {
if (appLocale.value !== i18n.global.locale.value)
setLanguage(appLocale.value).then(() => {})
})
const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI || {})
return {
targetLocale,
setLanguage,
}
}
测试多语言切换,在pages/index.vue中
<script lang="ts" setup>
const appLocale = useAppLocale()
const onSwitch = (lang: string) => {
appLocale.value = lang
}
</script>
<template>
<div>
<n-space>
<n-input />
<n-button @click="onSwitch('en-US')">
English
</n-button>
<n-button @click="onSwitch('zh-CN')">
中文
</n-button>
</n-space>
</div>
</template>
<style scoped>
</style>
测试切换多语言,当我们切换的时候我们发现会报错:
我们在auto-lang中添加如下代码:
const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI || {})
然后我们就不在报错了。 多语言配置完成。