3 Star 9 Fork 1

罪. / i18n-chain

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
README-CN.md 4.06 KB
一键复制 编辑 原始数据 按行查看 历史
罪. 提交于 2020-01-06 10:12 . docs: Sort title

说到国际化,你是否也常年奔波于复制粘贴的重复劳动里?像 t('home:submit') t('common:something:success') 这些没有任何提示,需要脑子去记,不仅开发效率低,而且键盘敲快一点就容易打错字母,重点是你基本发现不了这种错误。

我更喜欢有提示的代码,利用typescript,我发明了一种使用链式操作的i18n组件,并拥有所有提示,就类似 i18n.common.something.success 这种,代码可以自动补全,保证不会写错。

兼容性

IE Edge Chrome Firefox Safari Node
9+ 12+ 5+ 4+ 5+ *

定义本地化文件

// ./src/i18n/locales/en.ts

const en = {
  button: {
    submit: 'Submit',
    cancel: 'Go back',
  },
  user: {
    profile: 'Tom',
  },
};

export default en;
export type Locale = typeof en;
// ./src/i18n/locales/zh.ts

import { Locale } from './en';

const zh: Locale = {
  button: {
    submit: '提交',
    cancel: '返回',
  },
  user: {
    profile: '原罪',
  },
};

export default zh;

创建i18n实例

// ./src/i18n/index.ts

import { createI18n } from '@i18n-chain/*';
import en from './locales/en';

const i18n = createI18n({
  defaultLocale: {
    key: 'en',
    values: en,
  },
});

export default i18n;

导入语言

第一种, 直接定义

import { createI18n } from '@i18n-chain/*';
import zh from './locales/zh';

const i18n = createI18n({
  defaultLocale: { ... },
});

i18n._.define('zh', zh);

export default i18n;

第二种, 异步导入。当组件检测到语言未定义时,会自动触发loader函数

const i18n = createI18n({
  defaultLanguage: { ... },
  loader: (name) => import('./locales/' + name),
});

export default i18n;

切换语言

i18n._.locale('zh');

调用字符串

你可以随意地切换 i18n._.t('button.submit')i18n.button.submit,他们是等价的。唯一的区别就是前者无法享受到typescript的类型提示。

带参数的模板

当你想用参数的时候,你需要把模板写成数组的形式

const en = {
  property: ['{{property1}}template{{property2}}', { property1: value2, property2: value2 }],
};

数组第二个元素就是参数列表以及,你可以设置参数的默认值。

const en = {
  user: {
    profile: [
      'My name is {{name}}, I born in {{country}}, I am {{age}} old now, my birthday is {{birthday}}',
      {
        country: undefined,
        name: 'Tom',
        age: (value: number = 20) => {
          if (value <= 1) {
            return `${value} year`;
          } else {
            return `${value} years`;
          }
        },
        birthday: (value: Date) => {
          return value.toString();
        },
      },
    ],
  },
};

////////////////////////////////////
// 上面的代码可以自动推导出和下面一致的类型:
interface User {
  Profile {
    country: string | number;
    name?: string;
    age?: number;
    birthday: Date;
  }
}
/////////////////////////////////////

// 最小化调用
i18n.user.profile({
  age: 20,
  country: 'China',
});

// 增加可选的属性:`name`
i18n.user.profile({
  age: 30,
  country: 'Usa',
  name: 'Lucy',
});

方法参数 agebirthday 的区别是,age的形参中含有默认值(value: number = 20) => {...},而后者没有。有默认值意味着调用的时候可以不传参数。


普通参数如果没有默认值,需要设置成undefined,这样typescript才能正确识别,并强制要求调用者输入对应的参数值。

const en = {
  template: ['Hello, {{world}}', { world: undefined }]
};

更多使用方法

平台 使用版本
React & React-Native @i18n-chain/react
Vue 开发中...
Angular 开发中...
Taro @i18n-chain/taro
NodeJs & 原生JS @i18n-chain/core

案例

React I18n

TypeScript
1
https://gitee.com/geekact/i18n-chain.git
git@gitee.com:geekact/i18n-chain.git
geekact
i18n-chain
i18n-chain
master

搜索帮助