|
| 1 | +### 目标 |
| 2 | +完成全局多语言配置 |
| 3 | +## 开发 |
| 4 | +我们在开发的过程中避免不了会有使用多语言的情况,那么接下来我们就一起配置一下多语言的功能。 |
| 5 | +### 使用 |
| 6 | +在src目录下创建一个locales的文件夹,用于存放我们的多语言。再创建一个index.ts作为我们多语言的出口。 |
| 7 | +```typescript |
| 8 | +import { createI18n } from 'vue-i18n' |
| 9 | + |
| 10 | +export const defaultLocale = 'zh-CN' |
| 11 | + |
| 12 | +const i18n = createI18n({ |
| 13 | + // 是否启用传统模式,默认true,我们这里新项目我们不需要 |
| 14 | + legacy: false, |
| 15 | + // 本地化语言获取失败的时候是否输出警告 |
| 16 | + missingWarn: false, |
| 17 | + // 默认多语言 |
| 18 | + locale: defaultLocale, |
| 19 | + messages: { |
| 20 | + }, |
| 21 | + |
| 22 | +}) |
| 23 | + |
| 24 | +export default i18n |
| 25 | + |
| 26 | +``` |
| 27 | + |
| 28 | +### 导出 |
| 29 | +在main.ts中进行导出我们的多语言: |
| 30 | + |
| 31 | +```typescript |
| 32 | +import i18n from '~/locales' |
| 33 | +app.use(i18n) |
| 34 | +``` |
| 35 | +### 配置naive多语言 |
| 36 | +接下来我们来配置一下naiveui的默认多语言,我们先在locales下面创建一个lang的文件夹,用于存放我们的多语言部分。我们以中英文为例子,如果您还需要其他的多语言请自行添加配置。 |
| 37 | +接下来我们在lang中添加多语言文件分别为:en-US.ts何zh-CN.ts文件 |
| 38 | +en-US.ts |
| 39 | +```typescript |
| 40 | +import { dateEnUS, enUS } from 'naive-ui' |
| 41 | + |
| 42 | +export default { |
| 43 | + naiveUI: { |
| 44 | + locale: enUS, |
| 45 | + dateLocale: dateEnUS, |
| 46 | + }, |
| 47 | +} |
| 48 | +``` |
| 49 | +zh-CN.ts |
| 50 | +```typescript |
| 51 | +import { dateZhCN, zhCN } from 'naive-ui' |
| 52 | + |
| 53 | +export default { |
| 54 | + naiveUI: { |
| 55 | + locale: zhCN, |
| 56 | + dateLocale: dateZhCN, |
| 57 | + }, |
| 58 | +} |
| 59 | +``` |
| 60 | +然后在locales/index.ts中导入 |
| 61 | +```typescript |
| 62 | +import { createI18n } from 'vue-i18n' |
| 63 | +import zhCN from '~/locales/lang/zh-CN' |
| 64 | + |
| 65 | +export const defaultLocale = 'zh-CN' |
| 66 | + |
| 67 | +const i18n = createI18n({ |
| 68 | + // 是否启用传统模式,默认true,我们这里新项目我们不需要 |
| 69 | + legacy: false, |
| 70 | + // 本地化语言获取失败的时候是否输出警告 |
| 71 | + missingWarn: false, |
| 72 | + // 默认多语言 |
| 73 | + locale: defaultLocale, |
| 74 | + messages: { |
| 75 | + 'zh-CN': zhCN, |
| 76 | + }, |
| 77 | +}) |
| 78 | + |
| 79 | +export default i18n |
| 80 | +``` |
| 81 | + |
| 82 | +然后我们创建一个组合式的api用于处理我们的多语言,在composables下创建一个auto-lang.ts的文件 |
| 83 | +```typescript |
| 84 | +import i18n, { defaultLocale } from '~/locales' |
| 85 | + |
| 86 | +export const useAppLocale = createGlobalState(() => useStorage('locale', defaultLocale)) |
| 87 | +export const useAutoLang = () => { |
| 88 | + const appLocale = useAppLocale() |
| 89 | + const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI) |
| 90 | + |
| 91 | + return { |
| 92 | + targetLocale, |
| 93 | + } |
| 94 | +} |
| 95 | + |
| 96 | +``` |
| 97 | +然后在App.vue中使用 |
| 98 | +```vue |
| 99 | +<script setup lang="ts"> |
| 100 | +const appStore = useAppStore() |
| 101 | +const { layoutTheme, overridesTheme } = storeToRefs(appStore) |
| 102 | +useAutoDark() |
| 103 | ++ const { targetLocale } = useAutoLang() |
| 104 | +</script> |
| 105 | +
|
| 106 | +<template> |
| 107 | + <n-config-provider |
| 108 | ++ :locale="targetLocale.locale" |
| 109 | ++ :date-locale="targetLocale.dateLocale" |
| 110 | + :theme="layoutTheme" |
| 111 | + :theme-overrides="overridesTheme" |
| 112 | + > |
| 113 | + <n-global-style /> |
| 114 | + <app-provider> |
| 115 | + <router-view /> |
| 116 | + </app-provider> |
| 117 | + </n-config-provider> |
| 118 | +</template> |
| 119 | +
|
| 120 | +``` |
| 121 | + |
| 122 | +然后我们发现控制台会报如下的警告: |
| 123 | + |
| 124 | +本身我们是需要使用esm的方式去构建的,所以我们在vite.config.ts中做如下的配置: |
| 125 | +```typescript |
| 126 | +export default defineConfig({ |
| 127 | + define: { |
| 128 | + __VUE_I18N_FULL_INSTALL__: false, |
| 129 | + __VUE_I18N_LEGACY_API__: false, |
| 130 | + }, |
| 131 | +}) |
| 132 | +``` |
| 133 | +然后我们重启项目,发现我们的报错就没有了。 |
| 134 | + |
| 135 | +### 动态加载多语言 |
| 136 | +一次性加载所有的多语言是多余且没有必要的,所以接下来我们来实现一下动态加载我们的多语言的功能。 |
| 137 | +官方也提供了一个动态加载的例子[lazy loading](https://vue-i18n.intlify.dev/guide/advanced/lazy.html) |
| 138 | +我们在locales/index.ts中增加如下代码: |
| 139 | +```typescript |
| 140 | + |
| 141 | +export const loadLanguageAsync = async (lang: string = defaultLocale) => { |
| 142 | + const current = i18n.global.locale.value |
| 143 | + if (current !== lang) { |
| 144 | + const messages = await import(`./lang/${lang}.ts`) |
| 145 | + i18n.global.setLocaleMessage(lang, messages.default) |
| 146 | + } |
| 147 | + |
| 148 | + return nextTick() |
| 149 | +} |
| 150 | +``` |
| 151 | + |
| 152 | +然后我们在auto-lang中实现设置多语言。 |
| 153 | +首先我们可以先获取我们当前的系统语言,如果当前系统语言是其他语言那么我们默认加载其他的语言。 |
| 154 | +获取当前系统的语言我们可以通过vueuse中的useNavigatorLanguage的组合式api进行获取,实现代码如下: |
| 155 | +```typescript |
| 156 | +import i18n, { defaultLocale, loadLanguageAsync } from '~/locales' |
| 157 | + |
| 158 | +export const useAppLocale = createGlobalState(() => useStorage('locale', defaultLocale)) |
| 159 | +export const useAutoLang = () => { |
| 160 | + const appLocale = useAppLocale() |
| 161 | + const { isSupported, language } = useNavigatorLanguage() |
| 162 | + const setLanguage = async (lang: string) => { |
| 163 | + try { |
| 164 | + await loadLanguageAsync(lang) |
| 165 | + appLocale.value = lang |
| 166 | + } |
| 167 | + catch (e) { |
| 168 | + throw new Error(`Failed to load language: ${lang}`) |
| 169 | + } |
| 170 | + } |
| 171 | + if (isSupported.value) { |
| 172 | + if (language.value !== defaultLocale) |
| 173 | + setLanguage(language.value!).then(() => {}) |
| 174 | + |
| 175 | + watch(language, () => { |
| 176 | + setLanguage(language.value!).then(() => {}) |
| 177 | + }) |
| 178 | + } |
| 179 | + else { |
| 180 | + if (appLocale.value !== defaultLocale) |
| 181 | + setLanguage(appLocale.value).then(() => {}) |
| 182 | + } |
| 183 | + watch(appLocale, () => { |
| 184 | + if (appLocale.value !== i18n.global.locale.value) |
| 185 | + setLanguage(appLocale.value).then(() => {}) |
| 186 | + }) |
| 187 | + const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI || {}) |
| 188 | + |
| 189 | + return { |
| 190 | + targetLocale, |
| 191 | + setLanguage, |
| 192 | + } |
| 193 | +} |
| 194 | + |
| 195 | +``` |
| 196 | + |
| 197 | +测试多语言切换,在pages/index.vue中 |
| 198 | +```vue |
| 199 | +<script lang="ts" setup> |
| 200 | +const appLocale = useAppLocale() |
| 201 | +const onSwitch = (lang: string) => { |
| 202 | + appLocale.value = lang |
| 203 | +} |
| 204 | +</script> |
| 205 | +
|
| 206 | +<template> |
| 207 | + <div> |
| 208 | + <n-space> |
| 209 | + <n-input /> |
| 210 | + <n-button @click="onSwitch('en-US')"> |
| 211 | + English |
| 212 | + </n-button> |
| 213 | + <n-button @click="onSwitch('zh-CN')"> |
| 214 | + 中文 |
| 215 | + </n-button> |
| 216 | + </n-space> |
| 217 | + </div> |
| 218 | +</template> |
| 219 | +
|
| 220 | +<style scoped> |
| 221 | +
|
| 222 | +</style> |
| 223 | +
|
| 224 | +``` |
| 225 | +测试切换多语言,当我们切换的时候我们发现会报错: |
| 226 | + |
| 227 | +我们在auto-lang中添加如下代码: |
| 228 | +```typescript |
| 229 | +const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI || {}) |
| 230 | +``` |
| 231 | +然后我们就不在报错了。 |
| 232 | +多语言配置完成。 |
0 commit comments