成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Semantic-UI的React實現(四):基本元素組件的共通處理(父類)實現

開發 前端
上一篇(Semantic-UI的React實現(三):基本元素組件)已經提到過,基本元素組件的實現因為沒有復雜的交互,僅僅是CSS類的編輯和組裝,因此實現原理相對比較簡單。

上一篇(Semantic-UI的React實現(三):基本元素組件)已經提到過,基本元素組件的實現因為沒有復雜的交互,僅僅是CSS類的編輯和組裝,因此實現原理相對比較簡單。

但簡單的東西要想做的簡潔,往往不簡單。

抽象與封裝

想要簡潔高效地封裝數十個基本組件,將組件的相同處理部分抽象出來是非常必要的。在ES6中js新增了class關鍵字(當然這只是一個語法糖,其背后的處理原理仍然是prototype那一套東西。),有了這個關鍵字js在抽象與封裝的思想上比之前更進了一步。

當用“繼承”的思想去考慮問題后,組件的共通處理很明顯可以通過繼承一個共同父類來完成(通常我更愿意用接口而非繼承,無奈js學藝不精,不清楚接口繼承如何實現)。繼承以后,所有基本組件的以下處理,均可以由父類的處理完成:

  1. 編輯和組裝CSS類
  2. 渲染組件本身
  3. 封裝事件系統的方法回調

實現細節

編輯和組裝CSS類

在系列文章二的時候有提到過,基本組件的CSS編輯和組裝,在PropsHelper中實現,所有細節對外隱藏,組件僅需聲明相關屬性即可。如Header使用到的屬性:

  1. // 屬性定義 
  2. const PROP_TYPES = PropsHelper.getDefaultPropTypes().concat([ 
  3.   'size''sub''dividing''floated''aligned''inverted''inline''color' 
  4. ]);  

這些可用屬性的聲明,再加上Button組件實例的props,即可編輯和組裝出所需的CSS類名集合。在Header的render方法中,僅需調用:

  1. render() { 
  2.  
  3.   // 渲染元素 
  4.   let style = this.createElementStyle(this.props, PROP_TYPES) + ' header'
  5.   return super.render(style); 
  6.  

具體的生成style的細節,在Header的父類UiElement中:

  1. /** 
  2.  * 生成元素的style 
  3.  */ 
  4. createElementStyle(props, propsDef) { 
  5.  
  6.   ... 
  7.   return PropsHelper.createStyle(props, propsDef) + ' ' + style; 
  8.  

渲染組件

渲染組件也是共通處理實現的,作為子類的基本組件,僅需調用super.render即可:

  1. render(style, children, props) { 
  2.  
  3.   return React.createElement( 
  4.     this.props.as,                // 組件的html標簽(默認div) 
  5.     { 
  6.       id: this.props.id,          // 組件ID 
  7.       className: style,           // 組件class 
  8.       ...this.getEventCallback(), // 事件回調聲明 
  9.       ...props                    // 組件其他props(用于生成class的props不需要了) 
  10.     }, 
  11.     children ? children : this.props.children 
  12.   ); 
  13.  

最開始的時候,其實并沒有這個實現,各個組件的渲染過程還是留在組件各自的render中的。但隨著組件的增多,發現這部分代碼可重用性非常大。如果有特殊的組件不適用這個過程,直接在該組件中覆寫該方法即可。這對整體代碼的可維護性也有很大程度的提高。

事件系統的回調

這個功能目前還在實現中。我的目標是,任何組件僅需聲明而無需在該組件內部實現回調,由公共方法來實現回調處理。如一個Button想要用onClick方法,直接聲明:

  1. <Button onClick={this.handleClick}>Btn</Button> 

但在Button組件內部無需實現onClick的回調處理。(實際上也無法實現,因為Button的render處理是在其父類UiElement中實現的)

  1. const EVENT_CALLBACK = [ 
  2.   'onKeyDown''onKeyPress''onKeyUp'
  3.   'onFocus''onBlur'
  4.   'onChange''onInput''onSubmit'
  5.   'onClick''onContextMenu''onDoubleClick''onDrag''onDragEnd''onDragEnter'
  6.   'onDragExit''onDragLeave''onDragOver''onDragStart''onDrop''onMouseDown'
  7.   'onMouseEnter''onMouseLeave''onMouseMove''onMouseOut''onMouseOver''onMouseUp'
  8.   'onSelect'
  9.   'onTouchCancel''onTouchEnd''onTouchMove''onTouchStart'
  10.   'onScroll''onWheel'
  11.   'onLoad''onError'
  12.   'onTransitionEnd'
  13.   'onAnimationStart''onAnimationEnd''onAnimationIteration'
  14. ];  

對于事件系統的回調,在constructor中是這樣定義的:

  1. constructor(props) { 
  2.   super(props); 
  3.  
  4.   let eventProps = {}; 
  5.   for (let key in props) { 
  6.     if (key.indexOf('on') == 0 && EVENT_CALLBACK.indexOf(key) >= 0) { 
  7.       eventProps[key] = this.handleCallback.bind(this, key); 
  8.     } 
  9.   } 
  10.  
  11.   this.eventCallbacks = eventProps; 
  12.  

這個組件傳入的props中如果包含'onXXX'并且這個'onXXX'在EVENT_CALLBACK中有定義,則認為該組件聲明了一個事件系統的回調,那么UiElement將綁定這個回調的具體處理。處理過程如此實現:

  1. handleCallback(callback, e) { 
  2.  
  3.   if (this.props.callback) { 
  4.     this.props.callback(e); 
  5.   } 
  6.  

回顧

在UiElement中,實現了三類公共功能供基本組件類調用:

  1. 編輯和組裝CSS類
  2. 渲染組件本身
  3. 封裝事件系統的方法回調

實現以后,基本組件類的相同處理均被抽離出來,僅剩下一些聲明性質的代碼。例如Header組件的實現被簡化為:

  1. import React from 'react'
  2.  
  3. import PropsHelper from './PropsHelper'
  4. import UiElement from './UiElement'
  5.  
  6. // 屬性定義 
  7. const PROP_TYPES = PropsHelper.getDefaultPropTypes().concat([ 
  8.   'size''sub''dividing''floated''aligned''inverted''inline''color' 
  9. ]); 
  10.  
  11. /** 
  12.  * 標題組件 
  13.  */ 
  14. class Header extends UiElement { 
  15.  
  16.   // 類型定義 
  17.   static propTypes = { 
  18.     ...PropsHelper.createPropTypes(PROP_TYPES) 
  19.   }; 
  20.  
  21.   // 默認值定義 
  22.   static defaultProps = { 
  23.     ...PropsHelper.getDefaultPropsValue(PROP_TYPES) 
  24.   }; 
  25.  
  26.   /** 
  27.    * 取得渲染內容 
  28.    */ 
  29.   render() { 
  30.  
  31.     // 渲染元素 
  32.     let style = this.createElementStyle(this.props, PROP_TYPES) + ' header'
  33.     return super.render(style); 
  34.   } 
  35.  
  36. export default Header;  

這樣的好處是顯而易見的:

  1. 簡化實現代碼提高可閱讀性
  2. 封裝共通處理提高可維護性
  3. 通過方法覆寫保持可擴展性

通過這幾篇,基礎組件的封裝處理應該說完了,接下來的幾篇打算說說復雜組件的實現。在完成所有組件的封裝后,還打算擴展一些復雜組件的功能(代碼丑,只能多實現些功能了。總之要和官方做成不一樣的/(ㄒoㄒ)/~~)。

責任編輯:龐桂玉 來源: segmentfault
相關推薦

2016-10-18 21:39:59

Semantic-UIReact基本元素組件

2016-10-18 21:26:29

Semantic-UIReact架構

2016-10-18 21:31:52

Semantic-UIReact構造模塊

2020-10-18 21:41:34

軟件設計語言開發

2010-06-13 10:56:13

UML文獻

2012-03-15 10:04:06

移動web

2022-05-11 07:50:15

React UI組件庫前端

2018-01-23 08:24:57

HTTPS服務器加密

2020-10-21 08:38:47

React源碼

2020-12-11 09:38:49

Shell編程開發

2012-12-24 08:50:21

iOSUnity3D

2021-06-21 15:49:39

React動效組件

2015-03-19 15:13:20

PHP基本排序算法代碼實現

2010-09-03 12:55:15

CSSblockinline

2020-10-28 09:12:48

React架構Hooks

2021-03-31 08:01:24

React Portareactcss3

2014-06-06 09:01:07

DHCP

2022-08-01 07:56:23

React Hook開發組件

2023-04-28 09:30:40

vuereact

2023-09-05 20:17:18

typescriptPropTypesreact
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩欧美视频 | 红桃视频一区二区三区免费 | 久草精品视频 | 精品中文字幕在线 | 亚洲精品电影网在线观看 | 99热热| 成人免费在线播放视频 | 蜜桃特黄a∨片免费观看 | 黄色网址在线免费观看 | 91亚洲国产成人久久精品网站 | 中文字幕动漫成人 | 91爱爱·com | 亚洲区一区二 | 精品国产欧美 | av黄色免费在线观看 | 在线婷婷 | 一级黄在线观看 | 成人欧美一区二区三区1314 | 久久久久国产一区二区三区 | 亚洲欧美综合精品另类天天更新 | 一级毛片视频 | 亚洲国产精品久久久 | 日韩a v在线免费观看 | 999久久久久久久久6666 | 国产精品久久久久久久久久久免费看 | 久久久久久成人网 | 日本一区二区高清视频 | 国产美女一区二区三区 | 九九九国产 | 亚洲精品一区二区久 | 中文日本在线 | 好姑娘影视在线观看高清 | 欧美成人精品一区二区男人看 | 午夜a v电影 | 国产精品毛片一区二区三区 | 亚州av | 精品影院 | 99综合| 91啪影院| 亚洲欧美一区二区三区国产精品 | 国产一区二区在线播放 |