Semantic-UI的React实现(二):CSS类构造模块
更简单的类名标签Semantic-UI使用了更简单的类名声明。 <button type="button" class="btn btn-primary btn-lg active">Primary button</button> 在Semantic-UI中,类名更接近自然表述: <button class="ui blue large active button">Blue Button</button> 语义化的样式声明样式名并不是对某种组件进行的类型声明,可以通用到其他组件中。例如对于Label(标签)组件,也可用与button相同的CSS类声明其样式: <div class="ui blue large active label">Blue Label</div> 这样的好处是显而易见的,CSS类名语义化,刚方便使用和学习。 类名构造模块的实现从以上细节可以看出,每个组件的类声明均可由公用模块生成,每个组件仅仅声明本模块可使用的Props即可。以Button举例如下: import PropHelper from './PropHelper'; import UiElement from './UiElement'; ... let PROP_TYPES = ['primary','size','color','basic','active',...]; class Button extends UiElement { static propTypes = { ...PropHelper.createPropTypes(PROP_TYPES) }; render() { let style = this.createElementStyle(this.props,PROP_TYPES,'button'); return ( <div id={this.props.id} className={style} tabIndex='0'> {this.props.children} </div> ); } ... } Button类声明了其可以使用的class类名,通过共通处理生成style即可。生成style的共同处理,由PropsHelper类负责完成。 PropsHelperPropsHelper类主要的职责有两个:
PropsHelper作为工具类,相关处理过程中并无状态参与,方法应该声明为静态方法(static)。 props属性检查Semantci-UI中的所有class类属性的集合是可枚举的,这些属性直接在PropsHelper中定义即可: const BOOL_PROPS = ['ui','disabled','circular',...]; const STRING_PROPS = ['icon','appendClass',...],const NUMBER_PROPS = ['column','wide',const COLLECTION_PROPS = ['color','position',...]; 对于每个组件的属性检查定义,可以遍历传入的属性,并根据名字找到该属性的PropTypes定义。 class PropsHelper { ... /** * 生成属性检查 */ static createPropTypes(propTypes) { let result = {}; propTypes.forEach(function(typeName,index) { if (BOOL_PROPS.indexOf(typeName) >= 0) { result[typeName] = React.PropTypes.bool; } else if (STRING_PROPS.indexOf(typeName) >= 0) { result[typeName] = React.PropTypes.string; } else if (NUMBER_PROPS.indexOf(typeName) >= 0) { result[typeName] = React.PropTypes.number; } else if (COLLECTION_PROPS.indexOf(typeName) >= 0) { result[typeName] = React.PropTypes.oneOf(PROPS_VALUES[typeName]); } }); return result; } } class类集合组装与createPropTypes同样的思路,将传入的组件props遍历一遍,找到各自prop属性的类型定义,根据类型定义编辑和组装该组件的class类集合。 class PropsHelper { ... /** * 根据属性生成引用的class */ static createStyle(props,types) { let style = ''; for (let i = 0; i < types.length; i++) { let type = types[i]; if (props.hasOwnProperty(type)) { style += this.formatStyleValue(props[type],type); } } return style; } /** * 格式化属性对应的class */ static formatStyleValue(value,type) { // 如果是数字型属性 if (NUMBER_PROPS.indexOf(type) >= 0) { return ' ' + this.getNumberStr(value) + ' ' + type; } else if (COLLECTION_PROPS.indexOf(type) >= 0) { if (type == 'size') return ' ' + value; return ' ' + value + ' ' + type; } else if (BOOL_PROPS.indexOf(type) >= 0) { if (!value) return ''; if (type == 'imaged') return ' image'; if (type == 'iconed') return ' icon'; if (type == 'long') return ' long scrolling'; if (type == 'equalWidth') return ''; return ' ' + type; } else if (STRING_PROPS.indexOf(type) >= 0) { return ' ' + value; } else { return ''; } } } 这样实现以后,各组件在各自属性的定义和class类声明的处理时获得了两方面的益处:
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |