前端开发项目时,很多的时候都会用到国际化,今天我使用Vue3.2+TS+i18n来给大家实现一下项目的国际化,并且单独封装一个切换语种的组件,解决出现的bug,大家一步一步往下看。
1.安装i18n
npm install vue- i18n -- save
2.在src目录下,新建一个locales文件夹,此文件夹内新建一个index.ts文件,并写入如下内容
import { createI18n } from "vue-i18n" ;
import en from './language/en'
import zhCn from "./language/zhCn" ;
const i18n = createI18n ( {
locale: localStorage. getItem ( 'language' ) || 'zhCn' ,
fallbackLocale: 'en' ,
globalInjection: true ,
legacy: false ,
messages: { en, zhCn}
} )
export default i18n
3.这里大家可以看到,我把两种语言分别放到了不同的文件夹,所以这里大家需要在locales下新建一个language文件夹,并在下方新建en.ts和zhCn.ts文件,并分别写入如下内容
export default {
message: {
hello: 'hello world' ,
language: 'language'
}
}
export default {
message: {
hello: '你好,世界' ,
language: '语言'
}
}
4.都完成后需要在main.ts中注册,另外,本次我本次使用的ui框架是字节的ArcoDesign,大家使用其他的element或者antdesign也可以,都不影响。
import { createApp } from 'vue'
import './style.css'
import i18n from './locales'
import ArcoVue from '@arco-design/web-vue' ;
import '@arco-design/web-vue/dist/arco.css' ;
import ArcoVueIcon from '@arco-design/web-vue/es/icon' ;
import App from './App.vue'
const app = createApp ( App)
app. use ( i18n)
app. use ( ArcoVue) ;
app. use ( ArcoVueIcon) ;
app. mount ( '#app' )
5.我们封装一个组件来切换语种
< template>
< a- dropdown @ select = "handleSelect" : popup- max- height= "false" >
< a- button> { { curLanguage == 'zhCn' ? '中文' : 'Endlish' } } < icon- down/ > < / a- button>
< template #content>
< a- doption : value= "'zhCn'" : disabled= "curLanguage == 'zhCn'" > 中文< / a- doption>
< a- doption : value= "'en'" : disabled= "curLanguage == 'en'" > Endlish< / a- doption>
< / template>
< / a- dropdown>
< / template>
< script setup lang= "ts" >
import { useI18n } from "vue-i18n" ;
import { Message } from '@arco-design/web-vue' ;
import { computed } from "vue" ;
const i18n = useI18n ( )
const handleSelect = ( v: any ) => {
localStorage. setItem ( 'language' , v)
i18n. locale. value = v
Message. success ( {
content: v== 'zhCn' ? '当前语种为中文' : 'The current language is English' ,
duration: 2000
} )
} ;
const curLanguage = computed ( ( ) => {
return i18n. locale. value
} )
< / script>
< style scoped lang= "less" >
. arco- btn{
position: absolute;
right: 10px;
top: 5px;
}
. arco- dropdown- open . arco- icon- down {
transform: rotate ( 180deg) ;
}
< / style>
6.使用,直接通过调用{{ $t(“message.hello”) }}
< template>
< div>
{ { $t ( "message.hello" ) } }
< ChangeLan> < / ChangeLan>
< / div>
< / template>
< script setup lang= "ts" >
import ChangeLan from './components/tabLang.vue'
< / script>
< style scoped lang= "less" >
ul {
list- style- type: none;
li {
height: 30px;
line- height: 30px;
background- color: aqua;
margin- bottom: 10px;
}
}
< / style>
7.这里可能会报一个警告,You are running the esm-bundler build of vue-i18n. It is recommended to configure your bundler to explicitly replace feature flag globals with boolean literals to get proper tree-shaking in the final bundle.
那我们在vite.config.ts里面添加如下代码即可
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig ( {
plugins: [ vue ( ) ] ,
resolve: {
alias: {
'vue-i18n' : 'vue-i18n/dist/vue-i18n.cjs.js'
}
}
} )
8.假如我们的语种比较多,那么如果我们要新增语种,就需要全部改一下这样就很不方便,那么我们直接封装一个语言的映射文件,在locales文件夹下,新增一个langMap.ts文件,写入如下内容
export default {
langMap: new Map ( [
[ 'en' , 'English' ] ,
[ 'zhCn' , '中文' ] ,
[ 'ja' , 'わご' ] ,
] )
}
9.我们的组件现在也需要进行变化
< template>
< a- dropdown @ select = "handleSelect" : popup- max- height= "false" >
< ! -- 这里就是通过他的key,或者他的值 -- >
< a- button> { { langMap. langMap. get ( curLanguage) } } < icon- down/ >
< / a- button>
< template #content>
< ! -- langMap. langMap. entries ( ) 返回一个新的迭代器对象 比如 [ 'en' , 'English' ] -- >
< ! -- 第一个是他的key 可以写成item[ 0 ] ,第二个是他的值 item[ 1 ] -- >
< a- doption
v- for = "item in langMap.langMap.entries()"
: key= "item[0]"
: value= "item[0]"
: disabled= "curLanguage == item[0]"
> { { item[ 1 ] } } < / a- doption>
< / template>
< / a- dropdown>
< / template>
< script setup lang= "ts" >
import { useI18n } from "vue-i18n" ;
import { Message } from "@arco-design/web-vue" ;
import { computed } from "vue" ;
import langMap from "../locales/langMap" ;
const i18n = useI18n ( ) ;
const handleSelect = ( v: any ) => {
localStorage. setItem ( "language" , v) ;
i18n. locale. value = v;
Message. success ( {
content: ` ${ langMap. langMap. get ( v) } ` ,
duration: 2000 ,
} ) ;
} ;
const curLanguage = computed ( ( ) => {
return i18n. locale. value;
} ) ;
< / script>
< style scoped lang= "less" >
. arco- btn {
position: absolute;
right: 10px;
top: 5px;
}
. arco- dropdown- open . arco- icon- down {
transform: rotate ( 180deg) ;
}
< / style>
至此,Vue3.2+TS+Vite的国际化实现,并且解决了部分bug,封装了国际化切换组件,有需要的直接拿去用吧。