1. 程式人生 > >前端元件化設計思路

前端元件化設計思路

目前前端三大框架(Vue.js, Angular.js, React.js)都在引領著前端的元件化開發方向,元件化的前端開發方式的確為業務實現帶來了前所未有的方便,其實元件化開發早已經具有(YUI),但如何封裝一個優秀的元件,可能並不是每位前端開發者都能夠做好的。

元件封裝有一定的不確定性,更多時候是在做幾個方面的權衡,並且在業務不斷變化中,可能還會面臨一些調整和重構。

元件化開發的意義有很多,一些新手會狹隘地認為只是為了複用(包括對於模組化的理解),認為只有一個地方用就沒必要抽取封裝為元件,但實則不盡然:

 


  • 元件化是對實現的分層,是更有效地程式碼組合方式
  • 元件化是對資源的重組和優化,從而使專案資源管理更合理
  • 元件化有利於單元測試
  • 元件化對重構較友好

     


 

 

元件與模組


模組(Module)通常強調的是職責(分離、內聚),元件是可複用模組和相關依賴的封裝。

 

元件可以如下定義:

 


  • 可複用的模組,完成既定功能
  • 有明確的介面規定
  • 有上下文依賴、外部依賴資源的定義
  • 可以獨立釋出

     

 

 

元件設計的原則


新手常常會更多地從實現(如所用的框架Vue的元件實現方式)直覺角度定義元件,並且隘於視角較侷限,經驗較欠缺,對於職責劃分不合理。

 

以下原則儘可能使用,用得越多就元件的複用性就越好。

 


  1. 適用單一職責原則
  2. 適用開放封閉原則
  3. 追求短小精悍
  4. 避免太多引數
  5. 縮小信賴範圍和向穩定方向信賴
  6. 適用SPOT法則 (Single Point Of Truth,就是儘量不要重複程式碼,出自《The Art of Unix Programming》)
  7. 追求無副作用
  8. 追求引用透明
  9. 避免暴露元件內部實現
  10. 避免直接操作DOM
  11. 適用好萊塢法則 (好萊塢法則: Don’t call us, we’ll call you, 又稱IoC, Inversion of control, 控制反轉)
  12. 入口處檢查引數的有效性,出口處檢查返回的正確性
  13. 充分隔離變化的部分
  14. 元件和資料分享,信賴一致性的資料結構

     

 

 

自省的幾個問題


以上原則有點太教科書,不結合長期的實踐深刻理解,很難靈活運用,所以我設計了以下幾個自省問題,在思考一個元件時候,從這幾個問題入手,引導完善元件的設計。

 

 

這個元件可否(有必要)再分?


元件劃分的依據通常是 業務邏輯、功能,要考慮各元件之間的關係是否明確(如元件樹方式管理元件間依賴關係,兄弟元件不可見),以及元件的可複用度。

 

劃分粒度的大小需要根據實際情況權衡,太小會提升維護成本,太大又不夠靈活和高複用性。

每一個元件都應該有其獨特的劃分目的的,有的是為了複用實現,有的是為了封裝複雜度清晰業務實現。

 

這個元件的依賴是否可再縮減?


縮減元件依賴可以提高元件的可複用度,常用的方法是IoC(依賴注入),對外弱型別依賴。

 

 

這個元件是否對其它元件造成侵入?


一個元件的封裝性不夠,或者自身越界操作,就可能對自身之外造成了侵入,這種情況應該儘量避免,確保元件的生命週期能夠對其影響進行有效的管理(如destroy後不留痕跡)。

 

較常見的一種情況是:元件執行時對window物件新增resize監聽事件以實現元件響應視窗尺寸變化事件,這種需求的更好替代方案是:元件提供重新整理方法,由父元件實現呼叫(最終由根元件統一處理)。

次優的方案是,當元件destroy前清理恢復。

一個元件不應對其它兄弟元件造成直接影響。

 

這個元件可否複用於其它類似場景中?


需要考慮需要適用的不同場景,在元件介面設計時進行必要的相容。

 

 

這個元件當別人用時,會怎麼想?


介面設計符合規範和大眾習慣,儘量讓別人用起來簡單易上手,易上手是指更符合直覺。

 

 

假如業務需要不需要這個功能,是否方便清除?


各元件之前以組合的關係互相配合,也是對功能需求的模組化抽象,當需求變化時可以將實現以模組粒度進行調整。