vue-i18n 按需导入语言包

823 阅读2分钟

vue-i18n 按需导入语言包

全部导入

项目初始化的时候也会初始化i18n

一种做法是在options中直接导入所有语言包

import zh from "./zh.json";
import en from "./en.json";

const messages = {
  en,
  zh,
};
// 直接初始化导入
const i18n = createI18n({
  locale: language || "en", // 首先从缓存里拿,没有的话就用浏览器语言,
  fallbackLocale: "en", // 设置备用语言
  messages,
  legacy: false, // 过去式,为了兼容老版本,不写默认是true
  globalInjection: true, // 进行全局依赖
});

但如果支持的语言多了一下导入这么多语言包会对浏览器造成压力

因此更好的办法是按需导入

按需导入

i18n导入语言包的方式除了在初始化的options中导入,也可以使用vue-i18n的setLocaleMessage方法去中途导入,来实现按需导入

实现

需要创建三个方法来实现按需导入

  1. 初始化i8n,返回实例

    • 1.接受参数,创建i18n对象
    • 2.执行 setI18nLanguage 函数
    • 3.返回i8n对象
    export function setupI18n(options = { locale: "en" }) {
     const i18n = createI18n(options);
     setI18nLanguage(i18n, options.locale);
     return i18n;
    }
    
  2. 语言包导入函数

    /**
    *
    * @param i18n 对象
    * @param locale 语言
    * @returns
    */
    export async function loadLocaleMessages(i18n: any, locale: string) {
     // 导入语言包
     const messages = await import(`./${locale}.json`);
    
     // 往i18n对象假如语言包
     i18n.global.setLocaleMessage(locale, messages);
    
     return nextTick();
    }
    
  3. 切换语言

    /**
    *
    * 切换 i18n 语言
    * @param i18n i18n对象
    * @param locale 语言 zh | en
    */
    export function setI18nLanguage(i18n: any, locale: string) {
     if (i18n.mode === "legacy") {
       i18n.global.locale = locale;
     } else {
       i18n.global.locale.value = locale;
     }
     (document.querySelector("html") as any).setAttribute("lang", locale);
    }
    

这样就可以实现动态导入

注意如果你的i18n是根据浏览器语言来初始化的话,你需要在初始化i18n对象后立马检查当前语言是否导入语言包

const options = {
  locale: language || "en", // 首先从缓存里拿,没有的话就用浏览器语言,
  fallbackLocale: "en", // 设置备用语言
  messages,
  legacy: false, // 过去式,为了兼容老版本,不写默认是true
  globalInjection: true, // 进行全局依赖
};

const i18n = setupI18n(options);
if (!i18n.global.availableLocales.includes(language)) {
  await loadLocaleMessages(i18n, language);
}

最终的切换语言函数

  actions: {
    async changeLocale(locale: AppState["locale"]) {
      if (!i18n.global.availableLocales.includes(locale)) {
        await loadLocaleMessages(i18n, locale);
      }
      await setI18nLanguage(i18n, locale);
      this.locale = locale;
      // location.reload();
    },
  }