郑州互助盘网站开发,西樵营销网站制作,金华东阳网站建设,网页设计培训班学费多少钱随着国际化发展#xff0c;多语言的需求越来越常见#xff0c;单一的语言已经远不能满足需求了。作为一个组件库#xff0c;支持多语言也是基本能力。 多语言功能的本质其实是文本的替换#xff0c;一个词汇“OK”#xff0c;在英文语境下是“OK”#xff0c;日语语境下是…随着国际化发展多语言的需求越来越常见单一的语言已经远不能满足需求了。作为一个组件库支持多语言也是基本能力。 多语言功能的本质其实是文本的替换一个词汇“OK”在英文语境下是“OK”日语语境下是“確認”中文语境下可能是“确定”也可能是“确认”“好的”等等。 本文将以简单组件为切入点向大家展示Fusion组件库是如何支持多语言能力的。 单组件的多语言 我们以一个常见的组件Search举例用户输入内容后可通过点击“搜索”、“清除”按钮触发相应的事件简化代码后如下 class Search extends React.Component {render() {return (divinput /button搜索/buttonbutton清除/button/div);}
}export default Search;
复制代码多语言处理最简单直接的办法是直接替换文本不同语言环境下可能要将“搜索”替换为“search”、“サーチ”将“清除”替换为“clear”、クリア等。同时作为一个组件库涉及到的大多是简单词汇而不是句子因此我们首选配置化的方式 // 抽取语言包
// search-en-us.js
{search: search,clear: clear
}
// search-zh-cn.js
{search: 搜索,clear: 清除
}
复制代码import searchZhCN from search-zh-cn;class Search extends React.Component {static propTypes {locale: PropTypes.object};static defaultProps {locale: searchZhCN};render() {return (divinput /button{locale.search}/buttonbutton{locale.clear}/button/div);}
}export default Search;
复制代码这样就实现了单个组件Search的多语言支持。 但是为每个组件对应一个语言包文件的做法显然很不方便。Fusion Next作为一个PC端的React组件库有50组件内置词汇70多条目前有13个组件需要国际化语言能力。 以语种为单位将同一种语言下的映射关系放到一个文件里进行处理的方式更为高效。 多组件的多语言 为便于维护管理增强可拓展性我们以语种为单位抽取语言包。将同一语种下所有组件的语言对象{key: 文案}放到一起以displayName作为key语言对象作为value调整语言包如下 // 抽取语言包
// zh-cn.js
{Search: {search: 搜索,clear: 清除},Dialog: {},...
}
复制代码这也是Fusion现在语言包的结构 unpkg.com/alifd/next… 由于语言包结构的调整需要同时修改Search组件语言对象的默认值 import zhCN from zh-cn;class Search extends React.Component {...static defaultProps {locale: zhCN.Search}...
}export default Search;
复制代码在使用时用户将语言包对象以props参数的形式传给组件即可直接改变文案: import jaJP from xxxx/ja-jp.js;Search locale{jaJP.Search}
Dialog locale{jaJP.Dialog}
复制代码然而在web应用越来越复杂的现在很多项目里里可能会用到几十甚至上百个组件这样给每个组件手动传locale参数的方式一方面比较蠢另一方面开发者需要关心locale参数在语言切换时改变值的内容。 并且语言的设置大都是以项目或者页面为单位的有没有更聪明、对开发者更友好的使用方式呢 一键设置语言 如果你使用过Fusion Next或者体验过多语言demo就可以发现使用方式是这样的 import zhCN from zh-cn;ConfigProvider locale{zhCN}Search /Dialog /
/ConfigProvider
复制代码使用者在使用时基础组件时不用关心locale的变化子组件们共享了ConfigProvider组件上传入的语言配置更改这一配置可以一键设置子组件的语言包。如何实现的这一功能呢 React中如果不想通过逐层传递props或者state的方式来传递数据不如考虑考虑Context。 1. React Context共享上下文数据 借助Context可以实现跨层级的组件数据传递。 它的使用场景是生产者消费者模式在上面的例子中ConfigProvider就是生产者Search Dialog组件就是消费者。 他们分别通过一系列属性方法childContextTypes属性 getChildContext方法/contextTypes属性建立起一条通信线。 // 生产者
class ConfigProvider extends React.Component {// 声明Context对象static childContextTypes {nextLocale: PropTypes.object}// 返回Context对象getChildContext () {return {nextLocale: {}}}render () {return this.props.children;}
}
复制代码// 消费者
import zhCN from zh-cn;class Search extends React.Component {static propTypes {locale: PropTypes.object};static defaultProps {locale: zhCN.Search};// 声明需要使用的Context属性static contextTypes {nextLocale: PropTypes.object};render() {const locale Object.assign({}, nextLocale[Search], locale);return (divinput /button{locale.search}/buttonbutton{locale.clear}/button/div);}
}export default Search;
复制代码这样直接给ConfigProvider传递国际化参数就可以改变其子组件所使用的语言包。 数据传递的问题解决了按照这个思路对组件进行改造就可以完美支持一键切换语言了~ 事实上这个解决方案通用性很强只要子组件包括自定义组件都按上面的方式进行改造就可以支持语言包的切换。 但同时我们也发现改造工作高度重复都是新增contextTypes静态属性、对props和context上的locale进行merge。有没有对开发者基础组件开发者、业务组件开发者更友好的方式来降低这部分重复性工作呢 2.子组件的统一处理 Fusion为Util类组件ConfigProvider增加了一个静态方法ConfigProvider.config(Component)在这个函数里进行对于locale的改造工作它返回一个新的受控制的高阶组件HOCNewComponent。 NewComponent 相当于被 ConfigProvider 代理了一层。 在ConfigProvider.config()这个函数里 为组件新增contextTypes静态属性以便接收来自父组件的context为组件props、context传入的locale进行merge以便分发处理语言包文案这样只要子组件经过该函数处理就可以让ConfigProvider“遥控”语言包切换 import zhCN from zh-cn;class Search extends React.Component {static propTypes {locale: PropTypes.object};static defaultProps {locale: zhCN.Search};render() {return (divinput /button{locale.search}/buttonbutton{locale.clear}/button/div);}
}
// 经过统一处理
export default ConfigProvider.config(Search);
复制代码ConfigProvider.config(Component)的语言包文案分发处理逻辑简化如下 // ConfigProvider.jsx
function config(Component) {class ConfigedComponent extends React.Component {static propTypes {...(Component.propTypes || {}),locale: PropTypes.object,};static contextTypes {...(Component.contextTypes || {}),nextLocale: PropTypes.object,};render() {// 组件props上直接设置const { locale } this.props;// ConfigProvider遥控设置const { nextLocale {} } this.context;// 组件上直接设置语言包优先级高于在父组件ConfigProvider上设置。const newLocale Object.assign({},nextLocale[Component.displayName],locale);return (Component locale{newLocale}/);}}return ConfigedComponent;
}
复制代码这样就基本完成了组件库的多语言能力建设这也是Fusion Next组件库的多语言支持的思路。 除此之外ConfigProvider还有内置了其他通用能力例如组件的镜像反转RTLpure render开关、修改样式的默认前缀等更多可以查看 ConfigProvider源代码 和 使用文档 了解。 相关链接 Fusion 多语言切换demo: codepen.io/aboutblank/…Fusion ConfigProvider: fusion.design/component/c…github: github.com/alibaba-fus…转载于:https://juejin.im/post/5c6bb4d4f265da2dbd7ff1e0