react-intl 实现多语言

0. 前言

react-intl 实现多语言_第1张图片
timg.jpeg

最近在项目中添加了语言国际化,多语言的功能。

React-intl是雅虎的语言国际化开源项目FormatJS的一部分,通过其提供的组件和API可以与ReactJS绑定。



React-intl提供了两种使用方法,一种是直接调取API,另一种是引用React组件

React-intl提供的调取API方法如下:

1.导入injectIntl

import { injectIntl, FormattedMessage } from 'react-intl'

2.在组件中注入

export default connect(state => {
  return {
    ...state
  };
})(injectIntl(App));

export default connect(mapStateToProps,mapActionCreators)(injectIntl(App))

3.使用intl对象
我们通过第二步的注入,现在在我们在 组件的props 上会得到一个 intl 对象,它提供的方法和咱们上边介绍的组件基本相对应,这时候我们想要显示字符串,可以使用formatMessage方法:
如图:

react-intl 实现多语言_第2张图片
image.png

const {intl} = this.props;
  
let demo = intl.formatMessage({id: 'intl.name'});

4.应用


或使用defineMessages,来进行转换成字符串

1.导入injectIntldefineMessages

import { FormattedMessage, injectIntl, defineMessages } from "react-intl";

2.在组件中注入injectIntl

export default connect(state => {
  return {
    ...state
  };
})(injectIntl(App));

export default connect(mapStateToProps,mapActionCreators)(injectIntl(App))

3.使用defineMessages定义和intl对象

const {intl: { formatMessage }} = this.props;
const demo = defineMessages({
      placeholder: {
        id: "modal.invite.placeholder",
        defaultMessage: "请输入邀请人昵称",
      },
    });

4.应用


React-intl提供的React组件有如下几种:

包裹在需要语言国际化的组建的最外层,为包含在其中的所有组建提供包含id和字符串的键值对。

日期时间

1. 用于格式化日期,能够将一个时间戳格式化成不同语言中的日期格式。

传入时间戳作为参数:


输出结果:

4/5/2016

2. 用于格式化时间,效果与相似。

传入时间戳作为参数:


输出结果:

1:09 AM

3. 通过这个组件可以显示传入组件的某个时间戳和当前时间的关系,比如 "10 minutes ago" 。

传入时间戳作为参数:


输出结果:

now

10秒之后的输出结果:

10 seconds ago

1分钟之后的输出结果:

1 minute ago
数字量词

1.这个组件最主要的用途是用来给一串数字标逗号,比如10000这个数字,在中文的语言环境中应该是1,0000,是每隔4位加一个逗号,而在英语的环境中是10,000,每隔3位加一个逗号。

传入数字作为参数:


输出结果:

1,000

2. 这个组件可用于格式化量词,在中文的语境中,其实不太会用得到,比如我们说一个鸡腿,那么量词就是‘个’,我们说两个鸡腿,量词还是‘个’,不会发生变化。但是在英文的语言环境中,描述一个苹果的时候,量词是apple,当苹果数量为两个时,就会变成apples,这个组件的作用就在于此。

传入组件的参数中,value为数量,其他的为不同数量时对应的量词,在下面的例子中,一个的时候量词为message,两个的时候量词为messages。实际上可以传入组件的量词包括 zero, one, two, few, many, other 已经涵盖了所有的情况。


传入组件的量词参数可以是一个字符串,也可以是一个组件,我们可以选择传入组件,就可以实现量词的不同语言的切换。
输出结果:

messages
字符串的格式化

1. 这个组件用于格式化字符串,是所有的组件中使用频率最高的组件,因为基本上,UI上面的每一个字符串都应该用这个组件替代。

比如我们在locale配置文件中写了如下内容:

const zhCn = {
  hello:"你好,世界!",
};
export default zhCn;

使用这个组件的时候,我们这么写:


id指代的是这个字符串在locale配置文件中的属性名,description指的是对于这个位置替代的字符串的描述,便于维护代码,不写的话也不会影响输出的结果,当在locale配置文件中没有找到这个id的时候,输出的结果就是defaultMessage的值。

输出的结果:

你好,世界!

2.这个组件的用法和完全相同,唯一的不同就是输出的字符串可以包含HTML标签,但是官方不太推荐使用这个方法,这个组件的用法我就不举例了。

1. 安装

假设你已经在你的系统中安装了node.js和npm。

打开终端,进入项目根目录,输入以下指令安装React-intl:

npm install react-intl -save

注意:为了兼容Safari各个版本,需要同时安装 intl,intl在大部分的『现代』浏览器中是默认自带的,但是Safari和IE11以下的版本就没有了,这里需要注意一下。

安装intl需要在终端中输入以下指令:

npm install intl --save

2. 引用

import { FormattedMessage } from 'react-intl'

由于我使用的是ES6 的语法,所以是支持直接引用组件的。你当然可以使用ES5的方式引用。

require ReactIntl from 'react-intl'

3. 创建locale配置文件

这里,我们将文件命名为zh_CN.js、en_US.js、ja_JP.js、ko_KR.js,分别代表中文、美式英语、日语、韩语的配置包。

在zh_CN.js编写如下代码:

const zhCn = {
  hello:"你好,世界!",
};
export default zhCn;

在en_US.js编写如下代码:

const enUs = {
  hello:"Hello, world!",
};
export default enUs;

在ja_JP.js编写如下代码:

const jaJp = {
  hello:"こんにちは、世界!",
};
export default jaJp;

在ko_KR.js编写如下代码:

const koKr = {
  hello:"안녕, 세계!",
};
export default koKr;

我们就创建好了locale文件。

4. 使用

使用组件包裹住需要您需要进行语言国际化的组件,用法和React-redux的差不多,当包裹住某个组件的时候,这个组件本身和组件内部包含的子组件就可以获得所有React-intl提供的接口以及在中引入的locale配置文件的内容。

addLocaleData:引入本地的 localedata
IntlProvider:包裹需要翻译的组件,用来传递给子类语言信息
FormattedMessage :包裹需要实现多国语言的文字

react-intl 实现多语言_第3张图片
image.png

locale是传递需要国际化的语言的缩写,通过这个参数可以确定格式化日期,数字,量词的时候按照哪一种语言的规则,这个是规则是 intl提供的,一般浏览器会内置这个库,但是在Safari和IE11之前需要自己安装,安装的方法前面已经提及,请自己翻阅。

messages是用于传递刚刚我们在第3步中定义的配置文件的,从示例代码中我们可以看出,首先我们使用Import语句引入了配置文件,然后将配置文件的内容传递给了messages这个参数,此时组件中的所有组件都可以拿到配置文件中的内容了。

首先,我先获取localStorage中存储的语言,如果没有设置过,那么我就获取浏览器的语言navigator.language,如果设置过,那么就从localStorage中获取到你选择的语言。

react-intl 实现多语言_第4张图片
image.png

5. 实现效果

好了,看一下实现效果


react-intl 实现多语言_第5张图片
GIF.gif

6. 配置文件代码

一、

import React from "react";
import PropTypes from "prop-types";
import { IntlProvider, addLocaleData } from "react-intl";
import zh from "react-intl/locale-data/zh";
import en from "react-intl/locale-data/en";
import ja from "react-intl/locale-data/ja";
import ko from "react-intl/locale-data/ko";
import { chooseLocale, getLanguage } from "./../../lib/tools/utils.js";

const Intl = ({ children }) => {

  addLocaleData([...zh, ...en, ...ja, ...ko]);

  const defaultLang = getLanguage();

  return (
    
      {children}
    
  );
};

Intl.propTypes = {
  children: PropTypes.node.isRequired,
}

export default Intl;

二、

import enUs from "./../locale/en_US";
import zhCn from "./../locale/zh_CN";
import jaJp from "./../locale/ja_JP";
import koKr from "./../locale/ko_KR";

// 获取语言
export function getLanguage() {
  const lang = navigator.language || navigator.userLanguage; // 常规浏览器语言和IE浏览器
  const localStorageLang = localStorage.getItem("lang");
  const defaultLang = localStorageLang || lang;
  return defaultLang;
}

// 修改html.lang显示
export function changeHtmlLang(lang) {
  return document.getElementById("lang").lang = lang;
}

// 设置语言
export function setLanguage(lang) {
  const defaultLang = localStorage.setItem("lang", lang);
  return defaultLang;
}

// 匹配语言
export function chooseLocale() {
  switch (getLanguage()) {
  case "en":
    changeHtmlLang(getLanguage());
    return enUs;
  case "zh":
    changeHtmlLang(getLanguage());
    return zhCn;
  case "ja":
    changeHtmlLang(getLanguage());
    return jaJp;
  case "ko":
    changeHtmlLang(getLanguage());
    return koKr;
  default:
    changeHtmlLang(getLanguage());
    return zhCn;
  }
}

7. 结束语

好了,国际化已经over了,你可以试一试了!!!

你可能感兴趣的:(react-intl 实现多语言)