Skip to content

Commit 53d445c

Browse files
committed
添加 '29-多语言配置'
1 parent 49c5b04 commit 53d445c

File tree

1 file changed

+232
-0
lines changed

1 file changed

+232
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
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+
![image.png](https://cdn.nlark.com/yuque/0/2022/png/10377041/1668940070155-5ca02669-b10f-4982-9a6c-ad5c160591bb.png#averageHue=%2366819d&clientId=u524bb818-f7b3-4&from=paste&height=113&id=ua68bda95&name=image.png&originHeight=226&originWidth=3280&originalType=binary&ratio=1&rotation=0&showTitle=false&size=65016&status=done&style=none&taskId=u6f4bc1e5-683d-4687-874f-9fee7f26833&title=&width=1640)
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+
![image.png](https://cdn.nlark.com/yuque/0/2022/png/10377041/1668941781141-eb0c3520-e4a4-4e5c-a64d-5ec72ed7de51.png#averageHue=%23351f1f&clientId=u524bb818-f7b3-4&from=paste&height=259&id=u2b1b1bc2&name=image.png&originHeight=518&originWidth=1382&originalType=binary&ratio=1&rotation=0&showTitle=false&size=157224&status=done&style=none&taskId=u15e5ee6f-5839-497a-83bf-ea6c5d4c13d&title=&width=691)
227+
我们在auto-lang中添加如下代码:
228+
```typescript
229+
const targetLocale = computed(() => i18n.global.getLocaleMessage(appLocale.value).naiveUI || {})
230+
```
231+
然后我们就不在报错了。
232+
多语言配置完成。

0 commit comments

Comments
 (0)