項目中國際化的實現

國際化

國際化的目的

  1. 讓h5頁面在不一樣的語言環境下打開, 使用相應的語言
  2. 奔馳大老闆來中國出差旅遊要用的,祕書給他在外國裝好app來國內用(初心)

國際化的本質

  1. 根據語言來加載不一樣的json文件. json文件的內容是對各類文案和資源的配置.

國際化的語言判斷(判斷用戶所屬區域 或者 用戶所選擇語言)

  1. 入口 URL 附帶相關參數(目前咱們所選擇的方案, 視業務而定)
  2. 經過 IP 地址進行判斷

國際化的使用

  1. LocaleProvider 使用 React 的 context 特性,只需在應用外圍包裹一次便可全局生效。
const args = getUrlParam();
const lang = args.lang || 'zh_CN';
const langFile = require(`./components/locale-provider/${lang}`).default;

<LocaleProvider locale={langFile}> <Router history={history} routes={routes} /> </LocaleProvider> 複製代碼
  1. 編寫語言配置
//zh_CN.js
export default {
  locale: 'zh-cn',
  global: {},
  multi: {
    text: '你好',
  }
}

//en_US.js
export default {
  locale: 'en-us',
  // 全局: 好比 xx小時xx分鐘 該怎麼轉成英文
  global: {},
  multi: {
    text: 'hello',
  }
}
複製代碼
  1. 將語言配置注入組件中
import React, { Component } from 'react';
import { injectLocale } from '@/components/locale-provider';

@injectLocale()
export default class MultiLang extends Component {
  render() {
    const { locale: { multi } } = this.props;
    return <div className="multi">{multi.text}</div>;
  }
}

// 等價於
//export default injectLocale()(MultiLang);
複製代碼

國際化的實現

  1. LocaleProvider(本質是高階組件)

三種實現方式:javascript

  1. 組合props
  2. 繼承
  3. 以函數做爲children
// locale-provider/index.js
import React, { Component } from 'react';
import PropTypes from 'prop-types';

export default class LocaleProvider extends Component {
  getChildContext() {
    return {
      locale: { ...this.props.locale },
    };
  }

  render() {
    return React.Children.only(this.props.children);
  }
}

LocaleProvider.propTypes = {
  locale: PropTypes.object,
};

LocaleProvider.defaultProps = {
  locale: PropTypes.object,
};

LocaleProvider.childContextTypes = {
  locale: PropTypes.object,
};

export { default as injectLocale } from './injectLocale';
複製代碼
  1. injectLocale
import { Component, createElement } from 'react';
import PropTypes from 'prop-types';
import hoistStatics from 'hoist-non-react-statics';

export default function injectLocale(defaultLocale = {}) {
  return function wrapWithLocale(WrappedComponent) {
    class Inject extends Component {
      static contextTypes = {
        locale: PropTypes.object,
      };

      getLocale = () => {
        const { locale } = this.context;
        const localeFromContext = locale;
        return {
          ...localeFromContext,
          ...defaultLocale,
        };
      }

      addLocaleProps = () => ({ ...this.props, locale: this.getLocale() })

      render() {
        return createElement(WrappedComponent, this.addLocaleProps());
      }
    }

    return hoistStatics(Inject, WrappedComponent);
  };
}
複製代碼

題外話: decorator

什麼是裝飾器java

  1. ES7的語法, Object.defineProperty的語法糖
  2. 對類和**方法(不能修飾函數)**進行修飾, 在不改變原有接口的前提下, 加強它的功能(想象一下鋼鐵俠, 在不改變他是我的的前提下, 給他裝飾了不少武器, 使之無比強大)
  3. 裝飾器的實現
@testable
class A {}

function testable(target) {
  target.isTestable = true;
}

MyTestableClass.isTestable // true

// 等同於

class A {}
A = testable(A) || A;
複製代碼
class Person {
  @readonly
  name() { return `${this.first} ${this.last}` }
}

function readonly(target, name, descriptor){
  // descriptor對象原來的值以下
  // {
  // value: specifiedFunction,
  // enumerable: false,
  // configurable: true,
  // writable: true
  // };
  descriptor.writable = false;
  return descriptor;
}

readonly(Person.prototype, 'name', descriptor);
// 相似於
Object.defineProperty(Person.prototype, 'name', descriptor);
複製代碼

Tip: 這代碼是幾個月前寫的, 同時這是我第一次發表文章, 你們給新人一點鼓勵哈~react

相關文章
相關標籤/搜索