安装i18n
npm install vue-i18n
此处说下废话:处于好奇去查了国际化为什么叫i18n,原来是因为国际化的英文单词internationalization
太长了,掐头去尾取首字母i和尾字母n,中间刚好还有18个字母,就缩写为了i18n。
配置
在src文件夹下新添加文件夹,名为:locales
。在此文件夹下添加三个文件,en.js、zh.js、index.js
,目录结构如下:
三个文件的具体内容如下:
// index.js
import { createI18n } from 'vue-i18n'
import zh from './zh.js'
import en from './en.js'
const i18n = createI18n({
locale: localStorage.getItem('lang') || 'zh',
fallbackLocale: 'zh',
legacy: false,
messages: {
zh,
en
}
})
export default i18n
// zh.js
export default {
// 公用
common: {
edit: 编辑
},
// 日期相关
dayNames: {
day: '日',
week: '周',
month: '月',
season: '季',
year: '年',
},
}
export default {
// 公用
common: {
edit: edit
},
// 日期相关
dayNames: {
day: 'day',
week: 'week',
month: 'month',
season: 'season',
year: 'year',
},
}
引入
在项目的main.js中进行引入:
// main.js
// 引入国际化(此处只展示国际化相关代码)
import i18n from './locales/index.js';
const app = createApp(App).use(i18n);
使用
设置中英切换
// inedx.vue
<!-- 切换中英文 使用select即可 -->
<el-select v-model="currentLanguage" @change="changeLanguage" class="m-2" placeholder="Select" size="small">
<el-option
v-for="item in languagesOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<script setup>
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
const languagesOptions = [
{
label: '中文',
value: 'zh',
},
{
label: 'English',
value: 'en',
},
]
const currentLanguage = computed(() => {
return locale.value || localStorage.getItem('lang') || 'zh'
})
const changeLanguage = (val) => {
locale.value = val
// 切换语言后,存储到localStorage中
// 避免跳转页面或者刷新当前页后,语言又变成默认的中文
localStorage.setItem('lang', val)
}
</script>
此代码片段对应的页面内容:
在模板中使用,即在template标签中使用
使用$t
语法,示例如下:
<div class="test">{{ $t('common.edit') }}</div>
// 作为绑定的动态值使用时,去掉大花括号
<el-date-picker
v-model="test"
type="daterange"
range-separator="~"
:start-placeholder="$t(`dayNames.days`)"
/>
此处注意'common.edit'
的引号不能省略
在js中使用,即在script中使用
需要引入文件,使用t
语法
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const timeFiveList = computed(() => {
return [
{value: 'day', label: t(`dayNames.day`)},
{value: 'week', label: t(`dayNames.week`)},
{value: 'month', label: t(`dayNames.month`)},
{value: 'season', label: t(`dayNames.season`)},
{value: 'year', label: t(`dayNames.year`)},
]
})
如果遇到切换中英文后,对应文字并没有成功切换的,考虑使用computed
去监听。
在单独的js文件中使用
如图,项目中有类似这样的配置项文件(一般都是几个vue文件共同使用的一些常量)
// option.js
//性别
export const sexOption = [
{
value: '0',
label: '男',
},
{
value: '1',
label: '女',
},
];
然后在对应的vue中使用时,代码如下:
// xxx.vue
<template>
<el-radio-group v-model="sex">
<el-radio v-for="(sex, idx) in sexOption" :key="sex.id" :label="sex.value">
<span>{{ sex.label }}</span>
</el-radio>
</el-radio-group>
</template>
<script setup>
import { sexOption } from '@/utils/options.js';
</script>
这种情况下,要做国际化稍微麻烦一点点,但核心思想也是写两套语言,根据不同语言对应不同value
首先,option.js文件改为如下:
// options.js
export const i18nOptions = {
'zh': {
sexOption: [
{value: '0',label: '男',},
{value: '1',label: '女',},
];
},
'en': {
sexOption: [
{value: '0',label: 'male',},
{value: '1',label: 'female',},
];
}
}
在使用的地方,具体代码如下:
// xxx.vue
<template>
<el-radio-group v-model="sex">
<el-radio v-for="(sex, idx) in sexOption" :key="sex.id" :label="sex.value">
<span>{{ sex.label }}</span>
</el-radio>
</el-radio-group>
</template>
<script setup>
import { i18nOptions } from '@/utils/options.js';
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
// 获取当前语言
const currentLanguage = computed(() => {
return locale.value || localStorage.getItem('lang') || 'zh'
})
// 获取当前语言的options
const sexOption = computed(() => {
return i18nOptions[currentLanguage.value].sexOption
})
</script>
Element-Plus组件库的国际化
项目中用到的是element-plus,涉及到一些分页、时间选择组件等,是没有暴露出来专门的api去修改其中的文字的,比如: 时间选择插件:
分页器:
这个时候需要使用element-plus官网提供的配置组件Element-Plus中的Config Provider 全局配置
它提供的demo是针对分页器这个具体的组件,使用<el-config-provider :locale="locale">
标签进行一层包裹,但项目里用到的地方太多了,一个一个去包裹也太麻烦了。
所以另一种解决方案是,在项目的入口文件APP.vue中使用这个标签进行包裹,那么项目中所有用到的element组件都会被统一的国际化。具体代码如下:
<template>
<el-config-provider :locale="currentLanguage">
<router-view />
</el-config-provider>
</template>
<script setup>
// 按照官网demo引入中英文两种包
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import en from 'element-plus/dist/locale/en.mjs'
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
// 使用omputed监听语言的变化,确定该给element使用中文包还是英文包
const currentLanguage = computed(() => {
let lang = locale.value || localStorage.getItem('lang') || 'zh'
if (lang === 'zh') {
return zhCn
}
return en
})
</script>
此时切换到英文后,效果如下:
时间选择器:
分页器: