这样的切换语言功能,在一些组件库文档、框架使用文档、API 文档等都有这样的功能
那这个到底是怎么实现的?
国际化基本原理
创建下项目
npm init vite-app vue3-local
进入文件夹中
cd vue3-local
安装下依赖
npm install
创建 src/i18nTest/test.vue
<!--
@description: 国际化
-->
<template>
<div>{{ t('msg') }}</div>
</template>
<script setup lang='ts'>
// 1. 定义 msg 值的数据源
const messages = {
en: {
msg: 'hello word'
},
zn: {
msg: '你好世界'
}
}
// 2. 定义切换变量
const local = 'zn'
// 3. 定义赋值函数
function t(key) {
return messages[local][key]
}
</script>
App.vue 中导入 src/i18nTest/Local.vue
<template>
<Local />
</template>
<script setup lang="ts">
import Local from './i18nTest/Local.vue'
</script>
- 通过一个变量来控制语言环境
- 所有语言环境下的数据源要预先定义好
- 通过一个方法来获取当前语言下指定属性的值
- 该值即为国际化下展示值 (中/音切换)
启动下项目,打开 http://localhost:3000
npm run dev
我们修改下语言,为英文
基本效果是实现了,那我们在工作中,总不能这样去写吧!
我们可以使用这样一个插件 vue-i18n
[注]
vue3 下 vue-i18n 需要 v 9.0.x 的 i18n
vue-i18n 的使用分为 四个部分
- 创建 messages 数据源
- 创建 locale 语言变量
- 初始化 i18n 实例
- 注册 i18 实例
vue-i18n 实现国际化
安装 vue-i18n
npm install vue-i18n@next
src 目录下 创建 i18n/index.js 文件
import { createI18n } from 'vue-i18n'
// 这里可以把,msg 换成你要导入的语言包
const messages = {
en: {
msg: {
test: 'hello word'
}
},
zh: {
msg: {
test: '你好世界'
}
}
}
const locale = 'en'
const i18n = createI18n({
// 使用 composition API
legacy: false,
// 全局使用 t 函数
globalInjection: true,
locale,
messages
})
export default i18n
main.js 中 注册
import { createApp } from "vue";
import i18n from "./i18n";
import App from "./App.vue";
import "./index.css";
const app = createApp(App);
app.use(i18n)
app.mount("#app");
src/i18nTest/index.vue 文件中使用 i18n,修改 i18n/index.js 中为 locale = 'zh',可切换展示内容
<!--
@description: i18n 国际化演示
-->
<template>
<div>
<button @click="handleSetLanguage">切换</button>
</div>
<div>
setup 语法糖写法: {{ t('msg.test') }}
</div>
<div>
template 旧版写: {{ $t('msg.test') }}
</div>
</template>
<script setup lang='js'>
/* ------------------------ 导入 与 引用 ----------------------------------- */
import { ref, reactive } from 'vue'
import { useI18n } from 'vue-i18n' // 【注意】 不管新旧版的写法,都要引入 useI18n 才有办法使用
/* ------------------------ 变量 与 数据 ----------------------------------- */
const { t, locale } = useI18n()
/* ------------------------ 函数 与 方法 ----------------------------------- */
// 切换语言的方法
const handleSetLanguage = () => {
// 切换 i18n 的 locale
locale.value === 'en' ? locale.value = 'zh' : locale.value = 'en'
}
</script>
APP.vue 文件导入 src/i18nTest/index.vue
<template>
<div>
<I18nTest />
</div>
</template>
<script setup lang="ts">
import I18nTest from './i18nTest/index.vue';
</script>
[注]
该方案主要用于 自定义 语言包管理
后续可添加 持久化 等等
element-plus 国际化实现
[注]
element-plus的国际化,只针对element-plus组件做 国际化,并不会对一些后端返回数据,或者自定义内容做国际化也就是说,
element-plus引入的语言包只支持,element-plus组件
安装 element-plus
npm install element-plus
main.js 中导入element-plus
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import i18n from "./i18n";
import App from './App.vue'
const app = createApp(App)
app.use(ElementPlus)
app.use(i18n)
app.mount('#app')
src/i18nTest/index.vue 在原有基础上引入了 element-plus 的分页组件
引入 element-plus 组件已经翻译好的语言包
根据 local 来判断当前语言,并替换为对应语言包
<!--
@description: i18n 国际化演示
-->
<template>
<div class="middle">
<div>
<button @click="handleSetLanguage">切换</button>
</div>
<div>
setup 语法糖写法: {{ t('msg.test') }}
</div>
<div>
template 旧版写: {{ $t('msg.test') }}
</div>
<div style="width: 400px;">
<el-config-provider :locale="elementLocale">
<el-table mb-1 :data="[]" />
<el-pagination :total="100" />
</el-config-provider>
</div>
</div>
</template>
<script setup lang='js'>
/* ------------------------ 导入 与 引用 ----------------------------------- */
import { ref, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import zh from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
/* ------------------------ 变量 与 数据 ----------------------------------- */
const { t, locale } = useI18n()
const elementLocale = computed(() => (locale.value === 'zh' ? zh : en))
/* ------------------------ 函数 与 方法 ----------------------------------- */
// 切换语言的方法
const handleSetLanguage = () => {
// 切换 i18n 的 locale
locale.value = locale.value === 'zh' ? 'en' : 'zh'
}
</script>
<style scoped lang="scss">
.middle {
width: 100vw;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
}
</style>
小结
国际化的主要原理是通过一个功能函数,对语言进行切换
我们可以使用 vue-i18n 插件这个比较完善的插件替换不同语言包
如果要对组件库组件也进行国际化,那么直接去下载 element plus 对应语言包,不必自己再去一个一个翻译了