您好,登錄后才能下訂單哦!
這篇文章主要介紹“JS前端組件設計以業務為導向案例分析”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“JS前端組件設計以業務為導向案例分析”文章能幫助大家解決問題。
考慮一個業務場景。一個表單組件,用來采集用戶的基本信息,每個甲方爸爸都有自己的定制需求。比如樣式、比如要展示的控件種類。分析表單控件類型,假設分別可能有文本輸入框、單選框、多選框、下拉框等等。
我們很容易就能想到用動態表單來實現,支持自定義控件類型,支持自定義表單元素的樣式和行為。api設計為了易于擴展,泛型顯然更具可重用性。
一個基本的表單類型像這樣:
type FieldProps<T> = { label: string; name: string; value: T; onChange: (name: string, value: T) => void; };
創建一個接口,表示 Field 組件可以渲染的不同類型的表單元素:
interface FieldRenderer<T> { (props: FieldProps<T>): JSX.Element; }
接著,我們可以創建一個泛型的 Field 組件,根據傳入的泛型類型 T,來確定 Field 組件要渲染的表單元素類型以及 props 的類型。
function Field<T>({ label, name, value, onChange, render }: FieldProps<T> & { render: FieldRenderer<T> }) { return ( <div className="field"> <label htmlFor={name}>{label}</label> {render({ label, name, value, onChange })} </div> ); }
創建一些不同的 Field 組件渲染器,比如 TextInput、SelectInput、CheckboxInput。
const TextInput: FieldRenderer<string> = ({ label, name, value, onChange }) => ( <input type="text" id={name} name={name} value={value} onChange={(e) => onChange(name, e.target.value)} /> ); const SelectInput: FieldRenderer<string> = ({ label, name, value, options, onChange }) => ( <select id={name} name={name} value={value} onChange={(e) => onChange(name, e.target.value)}> {options.map(option=><option value={option.value}>{option.label}</option>)} </select> );
現在,我們可以在使用 Field 組件的時候,傳入不同的泛型類型,來渲染不同的表單元素了。
const DynamicForm = ({ fields, onSubmit }: { fields: FormField[], onSubmit: ()=>void }) => { //這里做一些映射之類的。。 return ( <form onSubmit={onSubmit}> {fields.map(field=><Field {...field} render={field.customComponent} />)} </form> ) }
以上,我們基本完成一個高度抽象化的組件設計。
現在,讓我們的目光從這個細節上挪開,切換到一個宏觀的視角上,重新審視項目整體架構的組件設計。一個前端架構通常會有其系統規范,比如統一的命名規范、代碼風格,合理的文件組織結構,前端開發的基礎設施,性能優化方案,依賴管理等。那么,我們如何在這個規范的框架下設計組件呢?
從整體角度規劃方案,我們可以對項目進行分層和模塊化的設計,實現不同模塊之間的解耦合。
分層設計是指將整個系統分成分層模塊,每一層模塊都有自己的職責和功能。前端的分層設計主要涉及以下幾層:展示層、控制層、邏輯層、服務層。模塊化設計是指將整個系統分成小的模塊,每個模塊都有自己的功能,不同模塊之間通過明確的接口進行通信和數據交換。在前端項目中,往往可以將不同的功能分配到不同的模塊中,甚至可以將某些通用的功能寫成獨立的模塊進行引入。
在實際業務中,我們通常需要將分層設計與模塊化設計相結合。在不同的層次上實現代碼結構的劃分和內部邏輯的編寫,不同的功能分配到不同的模塊,通用的功能寫成獨立的模塊引入,將代碼封裝成可復用的單元。
業務組件是在實現業務過程中抽象出來的組件,作用是在應用中復用業務邏輯。我們應該進行怎樣的抽象?簡單的功能如果抽象成組件,是否是一種過度設計?我們嘗試從以下幾個角度來思考這些問題。
在設計接口時,我們都知道,接口應該簡單清晰、易于擴展。比如一個loading flag, 我們通常會用布爾值來切換loading狀態,分別展示不同的UI界面。
比如一個發送驗證碼的按鈕,我們可能用isEnd
就能滿足展示不同按鈕文字的需求。但如果,我們分別需要在點擊按鈕前、點擊后的倒計時階段、倒計時進入到指定的時刻、倒計時結束后執行不同的邏輯。那么,我們就需要考慮將這個接口設計成字符串,以便于擴展。
同理,一些使用loading布爾值的場景,是否可以考慮設計為字符串,以便滿足更加個性化的需求?站在用戶的角度,你是否已經厭倦了在等待一份大體積的數據時看著一個動畫圈圈在轉動?
現在,我們來考慮組件的使用場景。
這個組件是否與業務邏輯綁定?比如一個登錄功能,可以是彈窗、也可以是單獨的頁面,它往往帶有以下功能:用戶名和密碼的前端校驗規則、對后端響應的處理、完成登錄后的邏輯處理。像這樣的組件,就不需要抽象,因為它難以通過修改參數就直接在其它系統中使用。
這個組件的功能有可能被重用嗎?如果是,我們如何做預先的接口設計?比如一個表格組件,通常包含以下狀態:要展示的數據、對數據的排序規則、數據過濾規則、用戶選擇器。我們初期可能據此做了4個接口:數據、排序、過濾、選擇器。隨著業務的擴展,我們可以預見后期的數據量開始加大,我們可能考慮增加一個分頁接口。但是分頁接口是否真的需要被集成在這個表格組件中?這是一個開放性的問題,相信不同的CRUD專家會有不同的解決方案。
組件的調用方式有多種,比如在模版文件中引入組件標簽直接調用,或通過函數調用(常見的message/loading類組件),或者通過接口調用(Ant Design的DatePicker)等。并沒有一套通用的標準來指定某種類型的組件的調用方式,總體還是取決于項目的需求和場景。
假設一個組件需要訪問api,這很常見。我們應該如何設計以便于在測試組件時隔離組件的功能?
import APIService from './APIService'; function MyComponent({ apiService }) { const fetchData = () => { const data = apiService.get('/data'); // 處理數據并返回結果 } return <>{/* 渲染組件的內容 */}</> } // 渲染組件時,可以將 APIService 實例作為 props 傳遞 const apiService = new APIService(); ReactDOM.render(<MyComponent apiService={apiService} />, document.getElementById('root'));
在組件內部,我們定義了一個 fetchData
函數,它可以在需要的時候調用 apiService.get()
來獲取數據。此時,我們可以輕松地模擬 apiService
,以進行單元測試,而不會對 MyComponent
的實現產生任何影響。
大多數時候,一個單一職責的組件的功能測試,是要比復合組件更容易的。使用標準和通用的API和數據格式,并將組件的功能和狀態限制在組件內部,確保組件可以獨立地進行測試。此外,我們還要考慮邊界測試,比如組件接收到無效的或非預期的參數該如何處理?
當然,組件不是顆粒度越細越好。是否遵循單一職責原則,不應該以功能點的數量,而是以功能和目標來衡量。
編寫一份前端組件設計文檔,明確記錄項目的設計標準和項目迭代過程中的變更,創建標準的組件庫以便于多人協作時的組件復用。尤其在一個多人協作的項目里,文檔能夠提供統一的開發規范,使得不同的開發人員在編寫不同的代碼時能保持一致的開發習慣。
我們已經有了設計的原則和需要考慮的因素,下面我們開始分析業務邏輯。
通常我們會有原型圖展示各個業務操作的流程和業務環節的邏輯關系,在設計組件時我們需要考慮如何支持這些流程和操作。比如根據業務邏輯,將整個項目分解為多個獨立的組件,劃分組件的接口和參數,指定其數據類型等。
此外,我們還要分析各種數據的處理和存儲方式。這里我們只討論前端的管理方式。比如一個給定的系統,我們通常會有用戶數據、產品數據、訂單數據等。我們可能會考慮使用狀態管理工具、Context API、組件間的通信、本地存儲等方式來管理這些數據。不同的場景需要采用不同的數據管理方法。
最后,我們要分析用戶交互的影響,考慮控制用戶的交互范圍。比如表單校驗、提高反饋信息和錯誤處理。
關于“JS前端組件設計以業務為導向案例分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。