Semantic-UI的React實(shí)現(xiàn)(三):基本元素組件
Semantic-UI官方的React組件化已經(jīng)快要接近完成了,最近開放了官網(wǎng):http://react.semantic-ui.com/。從官網(wǎng)看,基本組件已經(jīng)基本完備,還有幾個(gè)Addon也在進(jìn)行中。
基本元素組件
Semantic-UI中的基本元素均為純CSS類定義的組件,沒有js的操作,因此實(shí)現(xiàn)起來比較簡單。有了前面基礎(chǔ)類UiElement和輔助類PropsHelper的實(shí)現(xiàn),要實(shí)現(xiàn)一個(gè)基本元素組件非常輕松。
以Button組件舉例。Button組件可以單獨(dú)存在,也可以作為組組件使用。另外Button組件也允許簡單的Animation存在,即一對(duì)顯示/隱藏的組件可以隨鼠標(biāo)狀態(tài)而切換。外部調(diào)用的大致形式為:
- <Button.Group size='small'>
- <Button primary onClick={this.handleClickBtn1}>按鍵1</Button>
- <Button color='blue' onClick={this.handleClickBtn2}>按鍵2</Button>
- <Button animated onClick={this.handleClickBtn3}>
- <Button.Content visible>按鍵3顯示內(nèi)容</Button>
- <Button.Content hidden>按鍵3隱藏內(nèi)容</Button>
- </Button>
- </Button.Group>
調(diào)用方式實(shí)際上是很直觀的,屬性均作為props傳入到Button組件中,事件系統(tǒng)的回調(diào)方法也與普通方式并無二致。相對(duì)復(fù)雜的處理,是要整理所有組件的共通屬性,定義它們的類型和取值范圍。
Button
Button作為基本組件,有非常多常用的屬性。這些屬性在命名上,基本參照Semantic-UI的原有CSS類名,在Button.js中用常量PROP_TYPES來定義。
- const PROP_TYPES = [
- 'primary', 'secondary', 'animated', 'labeled', 'basic', 'inverted', 'color',
- 'size', 'fluid', 'active', 'disabled', 'loading', 'compact', 'circular', 'positive',
- 'negative', 'floated', 'attached', 'iconed', 'dropdown'
- ];
組件根據(jù)PropsHelper的相關(guān)方法來生成propTypes定義,并且通過父類(UiElement)的createElementStyle方法來編輯和組裝所使用的CSS類。另外,還通過父類的getEventCallback方法,來聲明相關(guān)的事件系統(tǒng)回調(diào)處理。
- class Button extends UiElement {
- // 類型定義
- static propTypes = {
- ...PropsHelper.createPropTypes(PROP_TYPES)
- };
- render() {
- // 生成元素style
- let style = this.createElementStyle(this.props, PROP_TYPES, 'button');
- return (
- <div id={this.props.id} className={style} {...this.getEventCallback()} tabIndex='0'>
- {this.props.children}
- </div>
- );
- }
- }
Button.Group
與Button組件類似,Group組件也繼承于UiElement以生成其聲明的公有屬性對(duì)應(yīng)的CSS類。
- // 屬性定義
- const GROUP_PROP_TYPES = [
- 'iconed', 'vertical', 'labeled', 'equalWidth', 'color',
- ];
- /**
- * 按鍵組組件
- */
- class Group extends UiElement {
- // 類型定義
- static propTypes = {
- ...PropsHelper.createPropTypes(GROUP_PROP_TYPES)
- };
- /**
- * 取得渲染內(nèi)容
- */
- render() {
- // 生成元素Style
- let style = this.createElementStyle(this.props, PROP_TYPES, 'buttons');
- return (
- <div id={this.props.id} className={style} {...this.getEventCallback()}>
- {this.props.children}
- </div>
- );
- }
- }
Button.Content
Content組件的實(shí)現(xiàn)更簡單,直接貼代碼。
- class Content extends React.Component {
- static propTypes = {
- visible: React.PropTypes.bool
- };
- render() {
- return (
- <div className={this.props.visible ? 'visible content' : 'hidden content'}>
- {this.props.children}
- </div>
- )
- }
- }
其他組件
通過以上示例可以看出,有了UiElement和PropsHelper類的處理,基本元素組件的實(shí)現(xiàn)是非常簡單的。只需聲明組件所使用的屬性,并使用父類方法編輯和組裝CSS類即可。其他組件如Label,Icon,Image,Grid等,均沿同一思路封裝即可完成。
難點(diǎn)是什么?
在封裝基本元素組件的過程中,我感覺難點(diǎn)在于:
- 封裝和抽象元素的共通處理(目前已基本成型)
- 管理眾多組件的共通屬性(目前還在摸索中)
看過官方相關(guān)處理的源碼,感覺思路還是大體一致的,這點(diǎn)讓我感覺多了一些自信(๑•̀ㅂ•́)و✧