vue-i18国际化

4/19/2023 vue插件

# 1.安装

npm

# 2.引入 i18n

*import* VueI18n *from* "./language/index";

app.use(VueI18n)

# 3.目录

  1. 创建文件夹 language
  2. 子目录 创建 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>
    思念是一种病
    蔡健雅/张震岳