最近学习有关vue3+ts项目,需要对显示进行中英切换。
以前只是知道做语言切换使用 i18n,不过一直没有上手用过。这次正好使用下试试。
1、安装
npm install vue-i18n
2、创建语言文件和目录结构
a、在 src 下创建 lang 目录
b、在 lang 下创建语言配置文件:zh.ts 和 en.ts
c、在 lang 下创建 index.ts 文件
对应目录结构如图:
这里因为只要中英切换,所以文件结构比较简单
3、编辑语言配置文件
这里做一个简单的配置
zh.ts 的配置
export default {
routers:{
logOut:'退出登录',
restore:'还原数据',
首页:'首页',
系统管理:'系统管理',
机构管理:'机构管理',
用户管理:'用户管理',
角色管理:'角色管理',
权限管理:'权限管理',
'测试1-1-1':'测试1-1-1',
商品管理:'商品管理',
手机分类:'手机分类',
分类管理:'分类管理',
分类测试:'分类测试',
系统工具:'系统工具',
日志管理:'日志管理',
接口文档:'接口文档',
}
}
en.ts 对应的配置
export default {
routers:{
logOut:'Log Out',
restore:'Restore data',
首页:'home page',
系统管理:'system',
机构管理:'organizational',
用户管理:'user',
角色管理:'role',
权限管理:'authority',
'测试1-1-1':'test',
商品管理:'commodity',
手机分类:'mobile',
分类管理:'classify',
分类测试:'testes',
系统工具:'until',
日志管理:'day',
接口文档:'nnterface ',
}
}
上述只对应路由配
4、在 vue 中注册
注册前要对语言文件整合以及 createI8n,这些在 lang/index.ts 中完成,代码如下:
import { createI18n } from 'vue-i18n'
// element-plus 中的语言配置
import elementEnLocale from 'element-plus/lib/locale/lang/en'
import elementZhLocale from 'element-plus/lib/locale/lang/zh-cn'
// 自己的语言配置
import enLocale from './en'
import zhLocale from './zh'
// 语言配置整合
const messages = {
en:{
...enLocale,
...elementEnLocale
},
'zh-cn':{
...zhLocale,
elementZhLocale
}
}
// 创建 i18n
const i18n = createI18n({
legacy: false,
globalInjection:true, // 全局模式,可以直接使用 $t
locale: 'zh-cn',
messages: messages
})
export default i18n
接下来要在 main.ts 中注册
import { createApp } from 'vue'
import App from './App.vue'
import i18n from './lang/index'
const app = createApp(App)
async function setupApp() {
app.use(i18n)
app.mount('#app')
}
setupApp()
5、使用
准备工作都完成了,现在就是使用了。
a、在 html 中使用(实例)
// 配置了全局
<div>{{$t('routers.logOut')}}</div>
// 未配置全局
<div>{{t('routers.logOut')}}</div>
<script lang="ts" setup>
// 需要引入 t
import { useI18n } from 'vue-i18n' //这个只能在setup 中用
const { t } = useI18n()//这个只能在setup 中用
</script>
b、ts文件 中使用(实例)
<script lang="ts" setup>
import i18n from '@/lang/index'
const t = i18n.global.t
const menuHome = { name: t('routers.logOut') }
</script>
6、动态路由菜单中英文切换
效果图:
代码如下:
<template>
<template v-for="menu in menuList" :key="menu.path">
<el-sub-menu v-if="menu.children && menu.children.length > 0 && !menu.redirect" :index="menu.path">
<template #title>
<!-- 动态组件的使用方法 -->
<el-icon>
<component class="icons" :is="menu.meta.icon" />
</el-icon>
<En :title="generateTitle(menu.meta.title)"></En>
</template>
<menu-item :menuList="menu.children"></menu-item>
</el-sub-menu>
<el-menu-item style="color: #f4f4f5" v-else :index="menu.path">
<!-- 动态组件的使用方法 -->
<el-icon>
<component class="icons" :is="menu.meta.icon" />
</el-icon>
<En :title="generateTitle(menu.meta.title)"></En>
</el-menu-item>
</template>
</template>
<script setup lang="ts">
import En from './En.vue'
import {generateTitle} from '@/utils/i18n'
defineProps(['menuList'])
</script>
<style scoped>
.icons {
width: 24px;
height: 18px;
margin-right: 5px;
}
</style>
En组件代码(./En.vue)
<template #title>{{ title }}</template>
<script setup lang="ts">
defineProps(['title'])
</script>
引入utils/i18n.ts函数generateTitle
会对路由的menu.meta.title进行中英文处理
import i18n from "@/lang/index"
export const generateTitle=(title:string)=>{
//i18n.global.te('routers.' + title) 只能在ts文件中用
const hasKey = i18n.global.te('routers.' + title) //返回布尔值,如果lang文件夹下没有配置routers.title 则返回false
if (hasKey) {
const translatedTitle = i18n.global.t('routers.' + title)
return translatedTitle
}
return title
}
如果是js文件
export function generateTitle(title) {
const hasKey = this.$te('route.' + title)
if (hasKey) {
const translatedTitle = this.$t('route.' + title)
return translatedTitle
}
return title
}
7、下面就是中英切换的 HTML 和 ts 代码
<template>
<el-dropdown placement="bottom-start" style="font-size: 30px;margin-left: 40px;">
<span class="el-dropdown-link">
<svg-icon icon-class="en" ></svg-icon>
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item @click="zh('zh-cn')">中文</el-dropdown-item>
<el-dropdown-item @click="en('en')">英文</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
import { useI18n } from 'vue-i18n'
const { locale } = useI18n()
const state = reactive({
curLanguage: 'zh-cn',
})
const zh = (e) => {
state.curLanguage = e
locale.value = state.curLanguage
}
const en = (e) => {
state.curLanguage = e
locale.value = state.curLanguage
}
</script>
<style scoped lang='scss'>
.userimg {
height: 42px;
width: 42px;
border-radius: 50%;
}
</style>