Vue3 + element-plus + I18n 国际化

前言

本文记录项目中集成i18n实现国际化,特在此记录,便于日后浏览。

组件库国际化方案

  • vue3
  • ElementPlus
  • vue-i18n

一、安装

1
npm i vue-i18n

二、配置

1. 新建index.ts,新建文件路径src/locales目录下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { createI18n } from 'vue-i18n'
// 语言包
import zhCN from "./lang/zh-CN";
import enUS from "./lang/en-US";
// 设置默认语言
const locale = localStorage.getItem('language') || 'zhCN'

//注册i8n实例并引入语言文件
const i18n = createI18n({
global: true,
locale: locale,
fallbackLocale: locale, // 默认语言
messages: {
zhCN,
enUS,
},
})
export default i18n

2.新建zh-CN.ts,存放中文,存放在src/locales/lang/

1
2
3
4
5
6
7
8
9
10
11
12
export default {
login:{
title:"后台管理系统",
username:"账号",
password:"密码",
code:"验证码",
rememberMe:"记住密码",
btn_login:"登 录",
btn_logining:"登 录 中...",
link_register:"立即注册"
}
}

3.新建en-US.js,存放英文,存放在src/locales/lang/

1
2
3
4
5
6
7
8
9
10
11
12
export default {
login: {
title: "Kola Management System",
username: "username",
password: "password",
code: "code",
rememberMe: "rememberMe",
btn_login: "login",
btn_logining:"logining...",
link_register:"register"
}
}

使用

1.在main.ts里引入并挂载到实例上

1
2
3
4
import App from '@/App.vue'
import i18n from '@/locales/index'

createApp(App).use(i18n).mount('#app')

2.在组件内部template内使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<template>
<div class="login">
<el-form ref="loginRef" :model="loginForm" :rules="loginRules" class="login-form">
//组件内的模板
<h3 class="title">{{`$t('login.title')`}}</h3>
<el-form-item prop="username">
// 动态绑定在vue
<el-input
v-model="loginForm.username"
type="text"
size="large"
auto-complete="off"
:placeholder="`$t('login.username')`"
>
<template #prefix><svg-icon icon-class="user" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="password">
// 动态绑定在vue
<el-input
v-model="loginForm.password"
type="password"
size="large"
auto-complete="off"
:placeholder="`$t('login.password')`"
@keyup.enter="handleLogin"
>
<template #prefix><svg-icon icon-class="password" class="el-input__icon input-icon" /></template>
</el-input>
</el-form-item>
<el-form-item prop="code" v-if="captchaEnabled">
// 动态绑定在vue
<el-input
v-model="loginForm.code"
size="large"
auto-complete="off"
:placeholder="`$t('login.code')`"
style="width: 63%"
@keyup.enter="handleLogin"
>
<template #prefix><svg-icon icon-class="validCode" class="el-input__icon input-icon" /></template>
</el-input>
<div class="login-code">
<img :src="codeUrl" @click="getCode" class="login-code-img"/>
</div>
</el-form-item>
<el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">{{`$t('login.rememberMe')`}}</el-checkbox>
<el-form-item style="width:100%;">
<el-button
:loading="loading"
size="large"
type="primary"
style="width:100%;"
@click.prevent="handleLogin"
>
<span v-if="!loading">{{`$t('login.btn_login')`}}</span>
<span v-else>{{`$t('login.btn_logining')`}}</span>
</el-button>

</el-form-item>
</el-form>

</div>
</template>

在el-input中要加入placeholder的值时 $t(‘login.username’) 要使用:placeholder. 示例如下
:placeholder=”$t(‘login.username’)”

//组件内的模板

1
<span>{{$t('login.rememberMe')}}</span>

语言切换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
<template>
<div>
<el-dropdown trigger="click" @command="handleChangeLanguage">
<div class="language-icon--style">
<svg-icon class-name="language-icon" icon-class="language" />
</div>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="item of languageOptions"
:key="item.value"
:disabled="langugae === item.value"
:command="item.value"
>
{{ item.label }}
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</div>
</template>

<script lang="ts" setup>
import { computed, ref } from 'vue'

const langugae = computed(() => localStorage.getItem('language'));
const languageOptions = ref([
{ label: "中文", value: "zhCN" },
{ label: "English", value: "enUS" },
]);

function handleChangeLanguage(langugae: any) {
localStorage.setItem(langugae);
setTimeout("window.location.reload()", 1000);
}
</script>

<style lang="scss" scoped>
.language-icon--style {
font-size: 18px;
line-height: 50px;
}
</style>