亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

JS前端組件設計以業(yè)務為導向?qū)嵺`思考

 更新時間:2023年03月13日 10:54:27   作者:Kiera  
這篇文章主要為大家介紹了JS前端組件設計以業(yè)務為導向?qū)嵺`思考,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

本文重點探討前端組件設計。我相信好的組件設計不僅需要考慮技術(shù)實現(xiàn),同時也需要考慮用戶體驗、可擴展性和易用性等多個方面。因此,我會重點強調(diào)這些方面的實現(xiàn)方法,從而更好地為產(chǎn)品的實際需求服務。我不打算在這里重復一些大家都耳熟能詳?shù)那岸私M件設計的原則和技巧。設計永遠是為需求服務的。

下面,讓我們進入正題。

一個組件設計的例子

考慮一個業(yè)務場景。一個表單組件,用來采集用戶的基本信息,每個甲方爸爸都有自己的定制需求。比如樣式、比如要展示的控件種類。分析表單控件類型,假設分別可能有文本輸入框、單選框、多選框、下拉框等等。

我們很容易就能想到用動態(tài)表單來實現(xiàn),支持自定義控件類型,支持自定義表單元素的樣式和行為。api設計為了易于擴展,泛型顯然更具可重用性。

一個基本的表單類型像這樣:

type FieldProps<T> = {
  label: string;
  name: string;
  value: T;
  onChange: (name: string, value: T) => void;
};

創(chuàng)建一個接口,表示 Field 組件可以渲染的不同類型的表單元素:

interface FieldRenderer<T> {
  (props: FieldProps<T>): JSX.Element;
}

接著,我們可以創(chuàng)建一個泛型的 Field 組件,根據(jù)傳入的泛型類型 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>
  );
}

創(chuàng)建一些不同的 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>
);

現(xiàn)在,我們可以在使用 Field 組件的時候,傳入不同的泛型類型,來渲染不同的表單元素了。

const DynamicForm = ({ fields, onSubmit }: { fields: FormField[], onSubmit: ()=>void }) => {
  //這里做一些映射之類的。。
  return (
    <form onSubmit={onSubmit}>
      {fields.map(field=><Field {...field} render={field.customComponent} />)}
    </form>
  )
}

以上,我們基本完成一個高度抽象化的組件設計。

現(xiàn)在,讓我們的目光從這個細節(jié)上挪開,切換到一個宏觀的視角上,重新審視項目整體架構(gòu)的組件設計。一個前端架構(gòu)通常會有其系統(tǒng)規(guī)范,比如統(tǒng)一的命名規(guī)范、代碼風格,合理的文件組織結(jié)構(gòu),前端開發(fā)的基礎設施,性能優(yōu)化方案,依賴管理等。那么,我們?nèi)绾卧谶@個規(guī)范的框架下設計組件呢?

模塊化設計原則

從整體角度規(guī)劃方案,我們可以對項目進行分層和模塊化的設計,實現(xiàn)不同模塊之間的解耦合。

分層設計是指將整個系統(tǒng)分成分層模塊,每一層模塊都有自己的職責和功能。前端的分層設計主要涉及以下幾層:展示層、控制層、邏輯層、服務層。模塊化設計是指將整個系統(tǒng)分成小的模塊,每個模塊都有自己的功能,不同模塊之間通過明確的接口進行通信和數(shù)據(jù)交換。在前端項目中,往往可以將不同的功能分配到不同的模塊中,甚至可以將某些通用的功能寫成獨立的模塊進行引入。

在實際業(yè)務中,我們通常需要將分層設計與模塊化設計相結(jié)合。在不同的層次上實現(xiàn)代碼結(jié)構(gòu)的劃分和內(nèi)部邏輯的編寫,不同的功能分配到不同的模塊,通用的功能寫成獨立的模塊引入,將代碼封裝成可復用的單元。

業(yè)務組件的設計因素

業(yè)務組件是在實現(xiàn)業(yè)務過程中抽象出來的組件,作用是在應用中復用業(yè)務邏輯。我們應該進行怎樣的抽象?簡單的功能如果抽象成組件,是否是一種過度設計?我們嘗試從以下幾個角度來思考這些問題。

1. 狀態(tài)與接口

在設計接口時,我們都知道,接口應該簡單清晰、易于擴展。比如一個loading flag, 我們通常會用布爾值來切換loading狀態(tài),分別展示不同的UI界面。

比如一個發(fā)送驗證碼的按鈕,我們可能用isEnd就能滿足展示不同按鈕文字的需求。但如果,我們分別需要在點擊按鈕前、點擊后的倒計時階段、倒計時進入到指定的時刻、倒計時結(jié)束后執(zhí)行不同的邏輯。那么,我們就需要考慮將這個接口設計成字符串,以便于擴展。

同理,一些使用loading布爾值的場景,是否可以考慮設計為字符串,以便滿足更加個性化的需求?站在用戶的角度,你是否已經(jīng)厭倦了在等待一份大體積的數(shù)據(jù)時看著一個動畫圈圈在轉(zhuǎn)動?

現(xiàn)在,我們來考慮組件的使用場景。

這個組件是否與業(yè)務邏輯綁定?比如一個登錄功能,可以是彈窗、也可以是單獨的頁面,它往往帶有以下功能:用戶名和密碼的前端校驗規(guī)則、對后端響應的處理、完成登錄后的邏輯處理。像這樣的組件,就不需要抽象,因為它難以通過修改參數(shù)就直接在其它系統(tǒng)中使用。

這個組件的功能有可能被重用嗎?如果是,我們?nèi)绾巫鲱A先的接口設計?比如一個表格組件,通常包含以下狀態(tài):要展示的數(shù)據(jù)、對數(shù)據(jù)的排序規(guī)則、數(shù)據(jù)過濾規(guī)則、用戶選擇器。我們初期可能據(jù)此做了4個接口:數(shù)據(jù)、排序、過濾、選擇器。隨著業(yè)務的擴展,我們可以預見后期的數(shù)據(jù)量開始加大,我們可能考慮增加一個分頁接口。但是分頁接口是否真的需要被集成在這個表格組件中?這是一個開放性的問題,相信不同的CRUD專家會有不同的解決方案。

2. 調(diào)用方式

組件的調(diào)用方式有多種,比如在模版文件中引入組件標簽直接調(diào)用,或通過函數(shù)調(diào)用(常見的message/loading類組件),或者通過接口調(diào)用(Ant Design的DatePicker)等。并沒有一套通用的標準來指定某種類型的組件的調(diào)用方式,總體還是取決于項目的需求和場景。

3. 測試

假設一個組件需要訪問api,這很常見。我們應該如何設計以便于在測試組件時隔離組件的功能?

import APIService from './APIService';
function MyComponent({ apiService }) {
  const fetchData = () => {
    const data = apiService.get('/data');
    // 處理數(shù)據(jù)并返回結(jié)果
  }
  return <>{/* 渲染組件的內(nèi)容 */}</>
}
// 渲染組件時,可以將 APIService 實例作為 props 傳遞
const apiService = new APIService();
ReactDOM.render(<MyComponent apiService={apiService} />, document.getElementById('root'));

在組件內(nèi)部,我們定義了一個 fetchData 函數(shù),它可以在需要的時候調(diào)用 apiService.get() 來獲取數(shù)據(jù)。此時,我們可以輕松地模擬 apiService,以進行單元測試,而不會對 MyComponent 的實現(xiàn)產(chǎn)生任何影響。

大多數(shù)時候,一個單一職責的組件的功能測試,是要比復合組件更容易的。使用標準和通用的API和數(shù)據(jù)格式,并將組件的功能和狀態(tài)限制在組件內(nèi)部,確保組件可以獨立地進行測試。此外,我們還要考慮邊界測試,比如組件接收到無效的或非預期的參數(shù)該如何處理?

當然,組件不是顆粒度越細越好。是否遵循單一職責原則,不應該以功能點的數(shù)量,而是以功能和目標來衡量。

4. 文檔

編寫一份前端組件設計文檔,明確記錄項目的設計標準和項目迭代過程中的變更,創(chuàng)建標準的組件庫以便于多人協(xié)作時的組件復用。尤其在一個多人協(xié)作的項目里,文檔能夠提供統(tǒng)一的開發(fā)規(guī)范,使得不同的開發(fā)人員在編寫不同的代碼時能保持一致的開發(fā)習慣。

分析業(yè)務邏輯

我們已經(jīng)有了設計的原則和需要考慮的因素,下面我們開始分析業(yè)務邏輯。

通常我們會有原型圖展示各個業(yè)務操作的流程和業(yè)務環(huán)節(jié)的邏輯關(guān)系,在設計組件時我們需要考慮如何支持這些流程和操作。比如根據(jù)業(yè)務邏輯,將整個項目分解為多個獨立的組件,劃分組件的接口和參數(shù),指定其數(shù)據(jù)類型等。

此外,我們還要分析各種數(shù)據(jù)的處理和存儲方式。這里我們只討論前端的管理方式。比如一個給定的系統(tǒng),我們通常會有用戶數(shù)據(jù)、產(chǎn)品數(shù)據(jù)、訂單數(shù)據(jù)等。我們可能會考慮使用狀態(tài)管理工具、Context API、組件間的通信、本地存儲等方式來管理這些數(shù)據(jù)。不同的場景需要采用不同的數(shù)據(jù)管理方法。

最后,我們要分析用戶交互的影響,考慮控制用戶的交互范圍。比如表單校驗、提高反饋信息和錯誤處理。

總結(jié)

當前端組件設計融合藝術(shù)與技術(shù),創(chuàng)造出優(yōu)美、流暢的用戶體驗時,似乎所有的麻煩都隨之而消失。通過組件化設計、數(shù)據(jù)管理、用戶交互分析等手段,我們可以打造出易維護、易擴展的代碼,為用戶提供舒適愉悅的體驗。在這個信息化的時代,前端組件設計越來越重要,只有注重細節(jié),不斷優(yōu)化性能和加強安全防范,我們才能成為一名真正的CRUD藝術(shù)家。

以上就是JS前端組件設計以業(yè)務為導向?qū)嵺`思考的詳細內(nèi)容,更多關(guān)于JS業(yè)務導向前端組件設計的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論