• Element + Vue I18n动态import加载国际化语言包翻译文件


    需求

    项目为多页应用,包含产品a、b、c、d、e,每个产品都有自己的翻译文件。
    一次加载所有翻译文件是极度不合理的。于是考虑动态加载。

    实现

    参考官方文档:延迟加载翻译

    项目结构

    │
    ├── dist // 静态资源输出目录
    │
    ├── src
    │   ├── assets
    │   ├── components
    │   ├── lang // 语言翻译文件
    │        ├── a
    │            ├── en_US.js
    │            └── zh_CN.js
    │        ├── b
    │            ├── en_US.js
    │            └── zh_CN.js
    │        ├── c
    │            ├── en_US.js
    │            └── zh_CN.js
    │        ├── d
    │            ├── en_US.js
    │            └── zh_CN.js
    │        ├── e
    │            ├── en_US.js
    │            └── zh_CN.js
    │   ├── pages
    │        ├── a
    │        ├── b
    │        ├── c
    │        ├── d
    │        ├── e
    │   ├── utils
    │        ├── i18n.js 
    │        ├── ...

    i18n.js

    import Vue from 'vue'
    import VueI18n from 'vue-i18n'
    
    import ElementLocale from 'element-ui/lib/locale'
    import enLocale from 'element-ui/lib/locale/lang/en'
    import zhLocale from 'element-ui/lib/locale/lang/zh-CN'
    
    // LANG:全局变量,从cookie中获取的当前语言版本,'zh_CN'、'en_US'
    // IS_INTL:全局变量,是否为国际版
    import { LANG, IS_INTL } from '@/constant'
    
    Vue.use(VueI18n)
    
    const i18n = new VueI18n({
      silentTranslationWarn: true
    })
    // 这里需要覆盖Element本地化函数,不然会冲突
    ElementLocale.i18n((key, value) => i18n.t(key, value))
    export default i18n
    
    /**
     * 更改vueI18n实例
     * @param lang 'zh_CN'、'en_US'
     */
    function setI18nLang (lang) {
      i18n.locale = lang
      // axios.defaults.headers.common['Accept-Language'] = lang
      document.querySelector('html').setAttribute('lang', lang)
      return lang
    }
    
    /**
     * 动态加载语言
     * @param path 当前路径(对应lang下文件夹名)
     */
    const _LANGS = ['zh_CN', 'en_US']
    const ELEMENT_LANG = {
      zh_CN: zhLocale,
      en_US: enLocale
    }
    let loadedLanguages = []
    
    export function loadLanguageAsync (path) {
     // lang目前是从cookie中获取,所以没有作为参数传递,此处lang也可作为变量传递
    
     // 如果cookie中没有获取到语言项,国际版默认初始化为英文
      const lang = LANG || (IS_INTL ? 'en_US' : 'zh_CN')
    
      if (!path || !_LANGS.includes(lang)) return
    
      if (i18n.locale !== lang) {
        if (!loadedLanguages.includes(lang)) {
          // 文件大时可拆分打包,目前项目中翻译文件均为4、5K左右,就没拆
          // return import(/* webpackChunkName: "lang-[request]" */ `@/lang/${path}/${lang}`).then(msgs => {
          return import(`@/lang/${path}/${lang}`).then(msgs => {
            const _temp = Object.assign(msgs.default, ELEMENT_LANG[lang])
            i18n.setLocaleMessage(lang, _temp)
            loadedLanguages.push(lang)
            return setI18nLang(lang)
          })
        }
        return Promise.resolve(setI18nLang(lang))
      }
      return Promise.resolve(lang)
    }

    main.js

    import Vue from 'vue'
    import App from './label.vue'
    import store from './store/index'
    import router from './router/index'
    
    import i18n, { loadLanguageAsync } from '@/utils/i18n'
    import '@label/plugins/element-ui'
    import '@/assets/styles/common.less'
    import AppComponents from '@label/components/index' // 注册全局组件
    
    Vue.config.productionTip = false
    Vue.use(AppComponents)
    
    // a页
    loadLanguageAsync('a').then(_ => {
      new Vue({
        i18n,
        store,
        router,
        render: h => h(App)
      }).$mount('#app')
    })

    切换语言组件

    主要操作:切换时setCookie后重刷页面
    原因:本来直接调用loadLanguageAsync是可以正常重刷语言包的,但是这里由于页面某些显示内容是来源于后端接口的,还是得重新请求,所以重刷了整页

    setCookie('jd.erp.lang', lang || 'en_US', 1, { path: '/', domain: CUR_HOST_SUFFIX })
    window.history.go(0)

    组件内容如下:

    // langs.vue
    <template>
      <el-dropdown
        class="icon-info icon-langs"
        @command="changeLang"
      >
        <img :src="imgSrc">
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item
            v-for="item in langs"
            :key="item.value"
            :command="item.value"
            :disabled="item.value === locale"
          >
            {{ item.label }}
          </el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </template>
    
    <script>
    import { LANG, CUR_HOST_SUFFIX } from '@/constant'
    import { setCookie } from '@/utils/utils'
    
    export default {
      name: 'langs',
      data () {
        return {
          imgSrc: require('@label/assets/icons/header-langs.svg'),
          locale: LANG,
          langs: [
            { label: '中文', value: 'zh_CN' },
            { label: 'English', value: 'en_US' }
          ]
        }
      },
      methods: {
        changeLang (lang) {
          this.locale = lang
          setCookie('jd.erp.lang', lang || 'en_US', 1, { path: '/', domain: CUR_HOST_SUFFIX })
          window.history.go(0)
        }
      }
    }
    </script>
     
  • 相关阅读:
    【Python】python3.6中实现同一行动态输出
    【Python】将python3.6软件的py文件打包成exe程序
    【Java】分布式RPC通信框架Apache Thrift 使用总结
    【Java】加载驱动方法
    【Java】Comparable和Comparator接口的区别
    【Java】接口(interface)VS抽象类
    【Ubuntu】PHP环境安装-phpstudy for linux版
    【Ubuntu】xrdp完美实现Windows远程访问Ubuntu 16.04
    【系统设计】会议室预定系统房间预定系统设计
    jmeter场景设计:业务占比
  • 原文地址:https://www.cnblogs.com/h2zZhou/p/12016786.html
Copyright © 2020-2023  润新知