摘要:上一篇的實現(xiàn)三基本元素組件已經(jīng)提到過,基本元素組件的實現(xiàn)因為沒有復(fù)雜的交互,僅僅是類的編輯和組裝,因此實現(xiàn)原理相對比較簡單。事件系統(tǒng)的回調(diào)這個功能目前還在實現(xiàn)中。
上一篇(Semantic-UI的React實現(xiàn)(三):基本元素組件)已經(jīng)提到過,基本元素組件的實現(xiàn)因為沒有復(fù)雜的交互,僅僅是CSS類的編輯和組裝,因此實現(xiàn)原理相對比較簡單。
但簡單的東西要想做的簡潔,往往不簡單。
抽象與封裝想要簡潔高效地封裝數(shù)十個基本組件,將組件的相同處理部分抽象出來是非常必要的。在ES6中js新增了class關(guān)鍵字(當(dāng)然這只是一個語法糖,其背后的處理原理仍然是prototype那一套東西。),有了這個關(guān)鍵字js在抽象與封裝的思想上比之前更進(jìn)了一步。
當(dāng)用“繼承”的思想去考慮問題后,組件的共通處理很明顯可以通過繼承一個共同父類來完成(通常我更愿意用接口而非繼承,無奈js學(xué)藝不精,不清楚接口繼承如何實現(xiàn))。繼承以后,所有基本組件的以下處理,均可以由父類的處理完成:
編輯和組裝CSS類
渲染組件本身
封裝事件系統(tǒng)的方法回調(diào)
實現(xiàn)細(xì)節(jié) 編輯和組裝CSS類在系列文章二的時候有提到過,基本組件的CSS編輯和組裝,在PropsHelper中實現(xiàn),所有細(xì)節(jié)對外隱藏,組件僅需聲明相關(guān)屬性即可。如Header使用到的屬性:
// 屬性定義 const PROP_TYPES = PropsHelper.getDefaultPropTypes().concat([ "size", "sub", "dividing", "floated", "aligned", "inverted", "inline", "color" ]);
這些可用屬性的聲明,再加上Button組件實例的props,即可編輯和組裝出所需的CSS類名集合。在Header的render方法中,僅需調(diào)用:
render() { // 渲染元素 let style = this.createElementStyle(this.props, PROP_TYPES) + " header"; return super.render(style); }
具體的生成style的細(xì)節(jié),在Header的父類UiElement中:
/** * 生成元素的style */ createElementStyle(props, propsDef) { ... return PropsHelper.createStyle(props, propsDef) + " " + style; }渲染組件
渲染組件也是共通處理實現(xiàn)的,作為子類的基本組件,僅需調(diào)用super.render即可:
render(style, children, props) { return React.createElement( this.props.as, // 組件的html標(biāo)簽(默認(rèn)div) { id: this.props.id, // 組件ID className: style, // 組件class ...this.getEventCallback(), // 事件回調(diào)聲明 ...props // 組件其他props(用于生成class的props不需要了) }, children ? children : this.props.children ); }
最開始的時候,其實并沒有這個實現(xiàn),各個組件的渲染過程還是留在組件各自的render中的。但隨著組件的增多,發(fā)現(xiàn)這部分代碼可重用性非常大。如果有特殊的組件不適用這個過程,直接在該組件中覆寫該方法即可。這對整體代碼的可維護(hù)性也有很大程度的提高。
事件系統(tǒng)的回調(diào)這個功能目前還在實現(xiàn)中。我的目標(biāo)是,任何組件僅需聲明而無需在該組件內(nèi)部實現(xiàn)回調(diào),由公共方法來實現(xiàn)回調(diào)處理。如一個Button想要用onClick方法,直接聲明:
但在Button組件內(nèi)部無需實現(xiàn)onClick的回調(diào)處理。(實際上也無法實現(xiàn),因為Button的render處理是在其父類UiElement中實現(xiàn)的)
const EVENT_CALLBACK = [ "onKeyDown", "onKeyPress", "onKeyUp", "onFocus", "onBlur", "onChange", "onInput", "onSubmit", "onClick", "onContextMenu", "onDoubleClick", "onDrag", "onDragEnd", "onDragEnter", "onDragExit", "onDragLeave", "onDragOver", "onDragStart", "onDrop", "onMouseDown", "onMouseEnter", "onMouseLeave", "onMouseMove", "onMouseOut", "onMouseOver", "onMouseUp", "onSelect", "onTouchCancel", "onTouchEnd", "onTouchMove", "onTouchStart", "onScroll", "onWheel", "onLoad", "onError", "onTransitionEnd", "onAnimationStart", "onAnimationEnd", "onAnimationIteration", ];
對于事件系統(tǒng)的回調(diào),在constructor中是這樣定義的:
constructor(props) { super(props); let eventProps = {}; for (let key in props) { if (key.indexOf("on") == 0 && EVENT_CALLBACK.indexOf(key) >= 0) { eventProps[key] = this.handleCallback.bind(this, key); } } this.eventCallbacks = eventProps; }
這個組件傳入的props中如果包含"onXXX"并且這個"onXXX"在EVENT_CALLBACK中有定義,則認(rèn)為該組件聲明了一個事件系統(tǒng)的回調(diào),那么UiElement將綁定這個回調(diào)的具體處理。處理過程如此實現(xiàn):
handleCallback(callback, e) { if (this.props.callback) { this.props.callback(e); } }回顧
在UiElement中,實現(xiàn)了三類公共功能供基本組件類調(diào)用:
編輯和組裝CSS類
渲染組件本身
封裝事件系統(tǒng)的方法回調(diào)
實現(xiàn)以后,基本組件類的相同處理均被抽離出來,僅剩下一些聲明性質(zhì)的代碼。例如Header組件的實現(xiàn)被簡化為:
import React from "react"; import PropsHelper from "./PropsHelper"; import UiElement from "./UiElement"; // 屬性定義 const PROP_TYPES = PropsHelper.getDefaultPropTypes().concat([ "size", "sub", "dividing", "floated", "aligned", "inverted", "inline", "color" ]); /** * 標(biāo)題組件 */ class Header extends UiElement { // 類型定義 static propTypes = { ...PropsHelper.createPropTypes(PROP_TYPES) }; // 默認(rèn)值定義 static defaultProps = { ...PropsHelper.getDefaultPropsValue(PROP_TYPES) }; /** * 取得渲染內(nèi)容 */ render() { // 渲染元素 let style = this.createElementStyle(this.props, PROP_TYPES) + " header"; return super.render(style); } } export default Header;
這樣的好處是顯而易見的:
簡化實現(xiàn)代碼提高可閱讀性
封裝共通處理提高可維護(hù)性
通過方法覆寫保持可擴(kuò)展性
通過這幾篇,基礎(chǔ)組件的封裝處理應(yīng)該說完了,接下來的幾篇打算說說復(fù)雜組件的實現(xiàn)。在完成所有組件的封裝后,還打算擴(kuò)展一些復(fù)雜組件的功能(代碼丑,只能多實現(xiàn)些功能了??傊凸俜阶龀刹灰粯拥?(ㄒoㄒ)/~~)。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80663.html
摘要:從服務(wù)端請求數(shù)據(jù)創(chuàng)建一個文件大胖分鐘前天氣不錯啊騷胖分鐘前出去玩啊老胖分鐘前去哪玩啊從服務(wù)端請求數(shù)據(jù)為了頁面的數(shù)據(jù)和服務(wù)端的保持聯(lián)系,設(shè)置每隔五秒向服務(wù)端發(fā)生一次請求在幫頂一下事件提交表單。。。。 React表單 首先,我們需要搭建一個React環(huán)境,用來實現(xiàn)效果: 先安裝React,這里我用的并不是最新版本的,所以需要選擇一個版本: jspm install [email protected]...
摘要:組件通信實現(xiàn)表單提交昨晚做了一個的例子,主要實現(xiàn)的是提交表單實現(xiàn)評論的功能,在做之前先簡單介紹一下。并稱為前端大框架,就目前來看,盡管發(fā)布了也在今年月份發(fā)布了,更不在話下,大家要是想學(xué)習(xí)的話可以去官網(wǎng)學(xué)習(xí)。 react組件通信實現(xiàn)表單提交 昨晚做了一個react的例子,主要實現(xiàn)的是提交表單實現(xiàn)評論的功能,在做之前先簡單介紹一下React。 showImg(https://segment...
摘要:屬性是一個組件的外部輸入。只會在開發(fā)模式下進(jìn)行屬性類型檢查,當(dāng)代碼進(jìn)行生產(chǎn)發(fā)布后,為了減少額外的性能開銷,類型檢查將會被略過。某個類的實例枚舉,屬性值必須為其中的某一個值。屬性為一個數(shù)組,且數(shù)組中的元素必須符合指定類型。 在第二篇文章 《新型前端開發(fā)方式》 中有說到 React 有很爽的一點就是給我們一種創(chuàng)造 HTML 標(biāo)簽的能力,那么今天這篇文章就詳細(xì)講解下 React 是如何提供這...
摘要:屬性是一個組件的外部輸入。只會在開發(fā)模式下進(jìn)行屬性類型檢查,當(dāng)代碼進(jìn)行生產(chǎn)發(fā)布后,為了減少額外的性能開銷,類型檢查將會被略過。某個類的實例枚舉,屬性值必須為其中的某一個值。屬性為一個數(shù)組,且數(shù)組中的元素必須符合指定類型。 在第二篇文章 《新型前端開發(fā)方式》 中有說到 React 有很爽的一點就是給我們一種創(chuàng)造 HTML 標(biāo)簽的能力,那么今天這篇文章就詳細(xì)講解下 React 是如何提供這...
閱讀 2614·2023-04-25 22:09
閱讀 2846·2021-10-14 09:47
閱讀 1943·2021-10-11 11:10
閱讀 2694·2021-10-09 09:44
閱讀 3390·2021-09-22 14:57
閱讀 2504·2019-08-30 15:56
閱讀 1623·2019-08-30 15:55
閱讀 783·2019-08-30 14:13