欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用vue-i18n进行项目国际化

程序员文章站 2022-05-16 09:31:54
...

vue-i18n方案文档

简介

安装

npm i -S vue-i18n

配置

cd project-path/src/***
mkdir i18n
cd i18n
touch index.js
mkdir lang
touch zh-CN.js en-US.js

1.zh-CN.js和en-US.js为具体语言包;

2.index.js负责实例化VueI18n ,加载应用语言包,export出i18n;

3.项目入口文件在实例化Vue时引入i18n:const app = new Vue({router, i18n, ...})

语言切换

// ./i18n/index.js
// 按需加载(此实现需要lang与语言包js文件同名,如'zh-CN'、'us-EN'等)
export function loadLanguageAsync (lang) {
  if (i18n.locale !== lang) {
    if (!loadedLanguages.includes(lang)) {
      return import(`./lang/${lang}`).then(msgs => {
        i18n.setLocaleMessage(lang, msgs.default[lang]);
        i18n.setDateTimeFormat(lang, msgs.default[lang]);
        i18n.setNumberFormat(lang, msgs.default[lang]);
        loadedLanguages.push(lang);
        return setI18nLanguage(lang);
      });
    };
    return Promise.resolve(setI18nLanguage(lang));
  }
  return Promise.resolve(lang);
}
// 设置语言包
function setI18nLanguage (lang) {
  i18n.locale = lang;
  return lang
}

// ***.vue
import { loadLanguageAsync } from '../i18n'
export default {
    methods: {
        chooseLanguage(lang) {
            localStorage.setItem('lang', lang);
            loadLanguageAsync(lang)
      }
    }
}

使用

// ./i18n/lang/zh-CN.js
const cn = {
    staff: {
        meta: {
            name: '姓名'
        }
    }
}
export default {
    'zh-CN': cn
}
// ./i18n/lang/en-US.js
const en = {
    staff: {
        meta: {
            name: 'Name'
        }
    }
}
export default {
    'en-US': en
}

// ./i18n/index.js
import Vue from 'vue'
import VueI18n from 'vue-i18n'
import langs from './lang/cn'
//默认加载中文
export const i18n = new VueI18n({
  locale: 'cn',
  messages: langs,
  numberFormats: langs,
  dateTimeFormats: langs
})

// main.js or index.js (项目入口文件)
import { i18n } from '$client/i18n';
new Vue({
  router,
  i18n,
  render: h => h(App)
}).$mount('#app');

// ***.vue
<span>{{ $t('staff.meta.name') }}</span>

常用方法

$t(path, locale, option) // text 文本替换,locale可单独设置语言,option可传参数替换模板
$tc(path, choice, locale, option) // text+choice 比$t多一个choice,可以选择模板内容(模板内容间用 | 分隔,如 香蕉|苹果|梨,最多只能使用三个选项,下标从0开始,当选项为2个时下标从1开始~~)
$te(path) // text+exist 判断当前语言包中path是否存在
$d(number|Date, path, locale) // date 时间格式化
$n(number, path, locale) // number  数字格式化(货币等)

// 更多细节参考官方文档:https://kazupon.github.io/vue-i18n/api/#vue-injected-methods

问题记录

语言包规范

/*
* 语言包主要分为三部分:
*   1.constant:项目内置的常量等;
*   2.customized:为了UI展示自定义内容
*   3.如element-ui内置的zh-CN等额外的语言包
* export时将各部分进行合并,隐藏细节以便使用
*/

// 以zh-CN.js为例
import merge from 'deepmerge'
import cnLocale from 'element-ui/lib/locale/lang/zh-CN';

const constant = {
    staff: {
        gender: {
          0: '保密',
          1: '男',
          2: '女'
        },
        // ...
    },
    account: {
        // ...
    },
    // ...
}
const customized = {
    staff: {
        state: {
          all: '全部'
        },
        meta: {
          name: '姓名',
          sector: '所在分支',
          phone: '手机号',
          state: '状态',
          operation: '操作'
        },
        // ...
    },
    account: {
        // ...
    },
    // ...
}
export default {
  'zh-CN': merge.all([constant, customized, cnLocale])
};

项目集成i18n工作量

  1. 涉及文案需要变化展示的代码都需要改,人工工程量较大。
  2. 语言包中key和value需要产品经理进行更合理的语义翻译。

待解决问题

  1. 内部封装库的(假设名字为comman-components)国际化方案如何实施?

    • 方案一:制作comman-components专用的语言包,业务层引入biz-packages时需要在对应语言包中导入comman-components的语言包,合并后导出。

      举例:如在comman-components中创建lang文件夹,里面做了一个中文包为cn.js,业务层中的zh-CN.js就可以import bizCnLocale from './comman-components/src/lang/cn',在最后export default {'zh-CN': merge.all([constant, customized, bizCnLocale ])},这样comman-components的语言包就可以生效了。

      业务层必须使用i18n,否则显示会出问题

    • 方案二:借鉴element-ui,制作comman-components专用的locale、lang、mixins,对外暴露接口。

      element-ui有完整的流程可供参考,此方案比较安全,业务层没有使用i18n时可以有默认语言,但逻辑复杂,工程量较大。

      业务层不强制使用i18n,但逻辑较为复杂

    • 方案三:在业务层把语言包做成一大个,其他业务要用的时候自己加上(类似方案一,但没有独立为文件,语言需要去公共空间拷贝)。

      临时方案,目前可用,但非长久之计

      业务层必须使用i18n,否则显示会出问题

  2. 服务端如何更好的配合国际化工作?
  3. 如果整个项目的同语言的语言包都放在一个文件中,文件体积是否过大且无必要?