摘要:在業(yè)務(wù)統(tǒng)一的情況下,僅僅修改組件用于配置的就可以滿足業(yè)務(wù)需求。避免了復(fù)雜的圖表配置,而將圖表進行有效拆分,通過聲明式的標(biāo)簽進行組合,從而使圖表更具擴展性。而對于顆粒度最細的組件,我們希望它是純粹的,木偶式的組件。
在前端業(yè)務(wù)開發(fā)中,組件化已經(jīng)成為我們的共識。沉淀和復(fù)用組件,是提高開發(fā)效率的利器。但在組件復(fù)用的過程中,我們往往會遇到這樣的問題,組件相似,卻在結(jié)構(gòu)或交互上有些許差別,需要對組件進行改造方可滿足需求。這個問題之前在 React實踐 - Component Generator 就有所提及。
之初,我們提出了組件配置式。在業(yè)務(wù)統(tǒng)一的情況下,僅僅修改組件用于配置的props就可以滿足業(yè)務(wù)需求。但隨著業(yè)務(wù)發(fā)生變化導(dǎo)致組件形態(tài)發(fā)生變化時,我們就必須不斷增加配置去應(yīng)對變化,便會出現(xiàn)配置泛濫,而在擴展過程中又必須保證組件向下兼容,只增不減,使組件可維護性的降低。
最近的項目開發(fā)中,@JasonHuang 提出了組件組合式開發(fā)思想,有效地解決了配置式所存在的一些問題。下面我將詳細闡述其思想與具體實現(xiàn)。
組件再分離對于組件的 view 層,我們期望組件是沒有冗余的,組件與組件間 view 重疊的部分應(yīng)當(dāng)被抽離出來,形成顆粒度更細的組件,使組件組合產(chǎn)生更多的可能。
這種 view 細化的組合式思想早已在我們團隊可視化庫 Recharts 中有所體現(xiàn)。Recharts 避免了復(fù)雜的圖表配置,而將圖表進行有效拆分,通過聲明式的標(biāo)簽進行組合,從而使圖表更具擴展性。
同樣,我們在組件上也希望秉承這種思想,先來看一下在現(xiàn)有業(yè)務(wù)比較典型的三個公共組件:
這三個組件無論在 UI 還是邏輯上均存在一定共性。在配置式中,我們會將這三個組件通過一個組件的配置變換來實現(xiàn),但無疑會提高單個組件內(nèi)部邏輯的復(fù)雜性。
再做一次分離!它們可由 SelectInput、SearchInput 與 List 三個顆粒度更細的組件來組合。而對于顆粒度最細的組件,我們希望它是純粹的,木偶式的組件。
例如 SelectInput 組件,組件狀態(tài)完全依賴傳入的 props,包括 selectedItem (顯示用戶所選項)、isActive (當(dāng)前下拉狀態(tài))、onClickHeader (反饋下拉狀態(tài))以及placeholder (下拉框提示)。我們來看一下它的簡要實現(xiàn):
class SelectInput extends Component { static displayName = "SelectInput"; render() { const { selectedItem, isActive, onClickHeader, placeholder } = this.props; const { text } = selectedItem || {}; return (); } }
當(dāng)組件被再次分離后,我們可以根據(jù)業(yè)務(wù)中的組件形態(tài)對其進行任意組合,形成統(tǒng)一層,擺脫在原有組件上擴展的模式,有效提高組件的靈活性。
邏輯再抽象那么有了 view 細化再重組的公共組件后,是不是就可以愉快地開發(fā)了?
是的,但組件層面的抽象不應(yīng)該只停留在 view 層面,組件中的相同交互邏輯和業(yè)務(wù)邏輯也應(yīng)該進行抽象。
ReactEurope 2016 小記 - 上 中提到復(fù)用高階函數(shù)的思想,編寫 Higher-Order Components (高階組件)來為基礎(chǔ)組件增加新的功能。
Higher-Order Components = Decorators + Components。在我們的組件中,也正是貫穿著這樣函數(shù)式的思想,來完成組件邏輯上的抽象,例如:
// 完成SearchInput與List的交互 const SearchDecorator = Wrapper => { class WrapperComponent extends Component { handleSearch(keyword) { this.setState({ data: this.props.data, keyword, }); this.props.onSearch(keyword); } render() { const { data, keyword } = this.state; return (); } } return WrapperComponent; }; // 完成List數(shù)據(jù)請求 const AsyncSelectDecorator = Wrapper => { class WrapperComponent extends Component { componentDidMount() { const { url } = this.props; fetch(url) .then(response => response.json()) .then(data => { this.setState({ data, }); }); } render() { const { data } = this.state; return ( ); } } return WrapperComponent; }
擁有 Decorator 之后,我們就能賦予組件能力了,例如合成 Search 組件:
@SearchDecorator class Search extends Component { render() { return (); } }
那么當(dāng)我們將邏輯抽象成為多個 Decorator 時,又該如何去組合呢?你是否還記得 React Mixin 的前世今生 中提到的方法?沒錯,就是compose!這里建議讀者 review 這篇文章,順便回顧一下Mixin與高階組件的不同點。
// SelectedItemDecorator為List與SelectInput的交互,讀者可以自行嘗試實現(xiàn) const FinalSelector = compose(AsyncSelectDecorator, SearchDecorator, SelectedItemDecorator)(Selector); class SearchSelect extends Component { render() { return (小結(jié)); } }
在配置式組件內(nèi)部,組件與組件間以及組件與業(yè)務(wù)間是緊密關(guān)聯(lián)的,而對于開發(fā)人員而言需要完成的僅僅是配置的工作。而組合式意圖打破這種關(guān)聯(lián),尋求單元化,通過顆粒度更細的基礎(chǔ)組件與抽象組件共有交互與業(yè)務(wù)邏輯的 Decorator,使組件更靈活,更易擴展,也使開發(fā)者能夠完成對于基礎(chǔ)組件的自由支配。
雖然組合式確實能解決配置式所存在的一些問題,但多層 Decorator 帶來的多層包裹,會對組件理解和調(diào)試造成一定困難,也"不能"使用外部公有的方法。同時組合式所基于的函數(shù)式編程的思想能否被整個團隊所接受,也是我們需要考量的問題。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/80088.html
摘要:在深入技術(shù)棧一書中,提到了基于的。書里對基于的沒有給出完整的實現(xiàn),在這里實現(xiàn)并記錄一下實現(xiàn)的思路。在這里最小的組件就是。對比范式與父組件的范式,如果完全利用來實現(xiàn)的,將操作與分離,也未嘗不可,但卻不優(yōu)雅。 在深入react 技術(shù)棧一書中,提到了基于Decorator的HOC。而不是直接通過父組件來逐層傳遞props,因為當(dāng)業(yè)務(wù)邏輯越來越復(fù)雜的時候,props的傳遞和維護也將變得困難且冗...
摘要:通常有兩種方式可以實現(xiàn)給一個類或?qū)ο笤黾有袨槔^承機制,使用繼承機制是給現(xiàn)有類添加功能的一種有效途徑,通過繼承一個現(xiàn)有類可以使得子類在擁有自身方法的同時還擁有父類的方法。 裝飾模式 (Decorator Pattern) 裝飾模式能夠?qū)崿F(xiàn)動態(tài)的為對象添加功能,是從一個對象外部來給對象添加功能。通常有兩種方式可以實現(xiàn)給一個類或?qū)ο笤黾有袨椋? 繼承機制,使用繼承機制是給現(xiàn)有類添加功能的一種...
摘要:相關(guān)設(shè)計模式裝飾者模式和代理模式裝飾者模式關(guān)注再一個對象上動態(tài)添加方法代理模式關(guān)注再對代理對象的控制訪問,可以對客戶隱藏被代理類的信息裝飾著模式和適配器模式都叫包裝模式關(guān)于新職責(zé)適配器也可以在轉(zhuǎn)換時增加新的職責(zé),但主要目的不在此。 0x01.定義與類型 定義:裝飾模式指的是在不必改變原類文件和使用繼承的情況下,動態(tài)地擴展一個對象的功能。它是通過創(chuàng)建一個包裝對象,也就是裝飾來包裹真實的...
摘要:想要使用語法的話,配合,這個插件,體驗更佳,這個插件在語法中實現(xiàn)了。這種方式最接近的單文件組件的寫法,如果一個完善項目從改成,用這種方法很快,只要加上和一些必要的變量類型就好了,然后用包裹就好。不推薦混入用這種方式寫,無法實現(xiàn)多繼承。 最近嘗試了一下 TypeScript,試著把一個 Vue 項目改成了 TypeScript 的,感覺還不錯 目前 Vue 和 TypeScript 的配...
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。對該漏洞的綜合評級為高危。目前,相關(guān)利用方式已經(jīng)在互聯(lián)網(wǎng)上公開,近期出現(xiàn)攻擊嘗試爆發(fā)的可能。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡...
閱讀 2141·2021-11-24 09:39
閱讀 1518·2019-08-30 15:44
閱讀 1974·2019-08-29 17:06
閱讀 3428·2019-08-29 16:32
閱讀 3570·2019-08-29 16:26
閱讀 2679·2019-08-29 15:35
閱讀 3047·2019-08-29 12:50
閱讀 1667·2019-08-29 11:15