i18n bug _0">前端开发项目时,很多的时候都会用到国际化,今天我使用Vue3.2+TS+i18n 来给大家实现一下项目的国际化,并且单独封装一个切换语种的组件,解决出现的bug ,大家一步一步往下看。
npm install vue- i18n -- save
ts _9">2.在src目录下,新建一个locales文件夹,此文件夹内新建一个index.ts 文件,并写入如下内容
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
ts zhCnts _30">3.这里大家可以看到,我把两种语言分别放到了不同的文件夹,所以这里大家需要在locales下新建一个language文件夹,并在下方新建en.ts 和zhCn.ts 文件,并分别写入如下内容
ts">
export default {
message: {
hello: 'hello world' ,
language: 'language'
}
}
export default {
message: {
hello: '你好,世界' ,
language: '语言'
}
}
ts uiArcoDesignelementantdesign_50">4.都完成后需要在main.ts 中注册,另外,本次我本次使用的ui框架是字节的ArcoDesign,大家使用其他的element或者antdesign也可以,都不影响。
ts">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.我们封装一个组件来切换语种
ts">< 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”) }}
ts">< 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>
i18n _It_is_recommended_to_configure_your_bundler_to_explicitly_replace_feature_flag_globals_with________boolean_literals_to_get_proper_treeshaking_in_the_final_bundle_145">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.
ts _147">那我们在vite.config.ts 里面添加如下代码即可
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'
}
}
} )
ts _164">8.假如我们的语种比较多,那么如果我们要新增语种,就需要全部改一下这样就很不方便,那么我们直接封装一个语言的映射文件,在locales文件夹下,新增一个langMap.ts 文件,写入如下内容
ts">
export default {
langMap: new Map ( [
[ 'en' , 'English' ] ,
[ 'zhCn' , '中文' ] ,
[ 'ja' , 'わご' ] ,
] )
}
9.我们的组件现在也需要进行变化
ts">< 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>
bug _233">至此,Vue3.2+TS+Vite的国际化实现,并且解决了部分bug ,封装了国际化切换组件,有需要的直接拿去用吧。