vue-i18国际化
4/19/2023 vue插件
# 1.安装
npm
# 2.引入 i18n
*import* VueI18n *from* "./language/index";
app.use(VueI18n)
# 3.目录
- 创建文件夹 language
- 子目录 创建 ch,en
# 4.配置文件
# language 目录下的 index
import { createI18n } from "vue-i18n"; // 引用
import store from "@/store"; //通过vux进行管理
import ch from "./ch/index"; //引用两个ch,en下的语言包
import en from "./en/index";
// 注册i8n实例并引入语言文件
const i18nObj = {
legacy: false, //vue3以上版本 开启api模式,组合api
// 全局注入 $t 函数
globalInjection: true, // 全局注入 $t 函数
getAsync: false, //异步
locale: getLanguageType(), // 切换语言包
messages: {
zh: ch,
en: en,
ja: ja,
},
};
// 获取本地存储
function getLanguageType(): string {
let lang: string = localStorage.getItem("lang") || "zh"; //查找本地是使用语言包
if (lang) {
//localStorage.setItem("lang", lang); //设置当前语言包
store.commit("setCurrentLanguage", lang); //存储到store中
}
return lang;
}
getLanguageType(); //执行
export default createI18n(i18nObj);
# 子目录下的语言包配置 (语言包同理)
const modulesFiles = import.meta.glob("../../views/*/language/ch.ts", {
eager: true,
import: "default",
}); //引入页面级中文ts文件 webpack的eager是否打包到main中
const dynamicModulesFiles = import.meta.glob(
"../../dynamicViews/*/language/ch.ts",
{ eager: true, import: "default" }
); //引入动态页面级中文ts文件
const modulesComponents = import.meta.glob(
"../../components/*/language/ch.ts",
{ eager: true, import: "default" }
); //引入组件级中文ts文件
const obj = {};
// 导入 view的ch文件
for (const path in modulesFiles) {
const splitArr: Array<string> = path.split("/"); //获取地址后已斜杠为截取条件
const indexOfViews: number = splitArr.indexOf("views"); //获取views 的索引
const indexOfLanguage: number = splitArr.indexOf("language"); // 获取language 的索引
const str: string = splitArr.slice(indexOfViews, indexOfLanguage).join("_"); //截取通过‘_’拼接
obj[str] = modulesFiles[path]; //格式:文件_目录=ch
}
// 导入page的ch文件 同理
for (const path in dynamicModulesFiles) {
const splitArr: Array<string> = path.split("/");
const indexOfViews: number = splitArr.indexOf("dynamicViews");
const indexOfLanguage: number = splitArr.indexOf("language");
const str: string = splitArr.slice(indexOfViews, indexOfLanguage).join("_");
obj[str] = dynamicModulesFiles[path];
}
// 导入 组件中的ch文件 同理
for (const path in modulesComponents) {
const splitArr: Array<string> = path.split("/");
const indexOfViews: number = splitArr.indexOf("components");
const indexOfLanguage: number = splitArr.indexOf("language");
const str: string = splitArr.slice(indexOfViews, indexOfLanguage).join("_");
obj[str] = modulesComponents[path];
}
export default {
...obj,
};
# 5.使用
在页面新建 language 里面包含两个语言包文件
# 引入 api
import { useI18n } from "vue-i18n";
const { t, d, mergeLocaleMessage, setLocaleMessage, locale, messages } =
useI18n();
# 调用
<div>
{{ $t("views_index.aa", { msg: "aa" }) }} //插值表达式 $t('文件_目录.语言属性‘)
</div>
# api 方法介绍
$t/t:转换国际化变量
locale:正在使用的语言包
message:语言包里面的具体内容
mergeLocaleMessage(locale,message)
- 合并语言包里面的内容,可替换修改
- 参数 1(语言包名字,信息)
setLocaleMessage(locale,message)
- 设置新的语言包,
- 参数 1(语言包名字,信息)
const list = {
en: {
content: "this a list",
aa:"lsit",
named: 'listname',
},
zh: {
content: "这是一个后台数据",
aa:"后台数据",
named: '名字',
}
}
//可直接修改messages里面的内容
const handle2 = () => {
messages.value.zh.views_index.content = "这是一个好方法";
messages.value.en.views_index.content = "this is goodfunciton";
};
const handle = () => {
console.log(mergeLocaleMessage);
//可使用 mergeLocaleMessage进行合并里面的内容
mergeLocaleMessage("en", {
views_index:list.en,
});
//可使用 setLocaleMessag设置新的语言包
setLocaleMessage("jp", {
views_index:list.zh
});
};
小提示:设置语言包 locale 要用双引号。使用 mergeLocaleMessage 注意路径要正确。
# 6.补充
# vux 使用
import { createStore } from "vuex";
export default createStore({
state: {
currentLanguage: "",
renderRouterTree: [], //渲染的路由菜单树
},
actions: {},
mutations: {
// 设置当前语言
setCurrentLanguage(state: any, msg: boolean) {
state.currentLanguage = msg;
},
setRenderRouterTree(state: any, msg: Array<any>) {
state.renderRouterTree = msg;
},
},
});
# 全局切换语言包
<el-dropdown trigger="click" @command="commandMenu">
<span class="el-dropdown-link"
>{{ $t("components_TopBar.language") }}: {{ currentLanguage }}
</span>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item
v-for="(item, index) in langArr"
:key="index"
:command="item"
>
<span :class="currentLanguage == mapLanguage(item) ? 'active' : ''"
>{{ mapLanguage(item) }}</span
>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
----------main
app.config.globalProperties.$languageMap = languageMap;
languageMap= zh:"中文",en: "English",
-----------切换按钮组件
const cns = getCurrentInstance() // 使用全局方法
const $languageMap=cns?cns.appContext.config.globalProperties.$languageMap:''
// 根据什么字体判断是是什么字。中文/英文/
const currentLanguage = computed(() => {
return $languageMap[store.state.currentLanguage];
});
// 获取全局有几种语言包
let langArr: Array<string> = reactive([]);
nextTick(() => {
langArr.push(...(that?.proxy?.$i18n.availableLocales || "")); //availableLocales:语言包数组
});
// 选择 acitve
const mapLanguage = (str: string): string => {
return $languageMap[str];
};
//选中后切换语言
const commandMenu = (str: string | number | object): void => {
store.commit("setCurrentLanguage", str);
localStorage.setItem("lang", store.state.currentLanguage);
locale.value = store.state.currentLanguage;
};
# 侧边栏如何使用路由切换
<a-menu :default-active="defaultActive" theme="dark" mode="inline" @select="selectMenu">
<a-menu-item v-for="(item, index) in renderRoutes"
ref="MenuItem"
:key="item.path"
:index="item.path"
>
{{ item.meta[local]}}
</a-menu-item>
</a-menu>
# 表单验证规则中使用
需要监听 locale 变化来改变验证信息
const message = computed(()=>(t('dynamicViews_page2.message'))) //通过计算属性获取到里面的值
const emailmessage = computed(()=>(t('dynamicViews_page2.emailmessage')))
const emailRules = ref([
{ type: "required", message: message.value},
{ type: "email", message:emailmessage.value}, //验证规则
])
const tableShow = ref(true)
watch(locale, () => { //locale
tableShow.value=false
nextTick(() => {
emailRules.value=[
{ type: "required", message: message.value}, 监听locale发生变化的时候验证规则发生改变
{ type: "email", message:emailmessage.value},// 重新赋值
]
tableShow.value=true // 重置表单
})
<v-input style="width:100%" v-if="tableShow" @updateinput="updateinput" :placeholder="$t('dynamicViews_page2.placeholder')" :rules="emailRules" v-model="modelValue"></v-input>
a:{{ modelValue }}
</div>