點選一鍵訂閱《雲薦大咖》專欄,獲取官方推薦精品內容,學技術不迷路!
可重用的程式碼可以減少重複勞動。一個軟體中,會有很多類似的業務場景。將這些場景抽象成可重用的程式碼。開發新功能時,重用程式碼可減少重複勞動。
可重用的程式碼可以減少因需求變動,導致多次改動和漏改的情況。試想,要修改全站提交按鈕的顏色,如果全站有100個包含提交按鈕的頁面,每個頁面的按鈕的樣式都沒複用,這改動量和漏改的風險都很大。如果做成可重用的,則只需改動一處。
如何寫出可重用的程式碼?
程式碼塊的職責越多,越難被複用。寫出可重用的程式碼就是:識別,分離出可複用的部分。
考慮這樣的場景:程式碼塊A 的功能是獲取介面資料,並渲染 UI。程式碼塊B 的 UI 和 A 一樣,但獲取的介面資料不一樣。程式碼塊C 獲取的資料和 A 一樣,但 UI 和 A 不一樣。A,B,C 之間的程式碼都不能被複用。
要改成可複用的程式碼,就是將可複用的 UI,獲取介面資料的程式碼獨立出來。
下面,我們來看些常見的可複用的部分和複用方法。
一、UI 展示
UI 展示為外觀的展示,包含:HTML 和 CSS。不包含資料的獲取和事件處理。
用元件可以實現 UI 展示程式碼的複用。這樣的元件被稱為展示元件。資料和事件處理通過屬性傳入。Ant Design 之類的元件庫裡的元件均為展示元件。如下是 React 實現的新聞列表:
import React from 'react'
import s from './style.scss'
import Item, {IItem} from './item'
export interface INewsListProps {
list: IItem[],
onItemClick: (id: number) => void
}
const NewsList: FC<INewsListProps> = ({ list, onItemClick }) => {
return (
<div className={s.list}>
{
list.map(item => (
<Item
key={item.id}
onClick={onItemClick}
payload={item}
/>
))
}
</div>
)
}
export default React.memo(NewsList)
二、介面呼叫
介面呼叫有兩部分可以複用:
介面請求和響應的通用處理。
具體介面的呼叫。
三、介面請求和響應的通用處理
介面呼叫時,常常要做一些通用的處理。比如:
前後端分離的網站,要在介面的請求頭中要加 token 來標識使用者。
介面報錯時,要將錯誤碼轉化成對使用者友好的錯誤資訊。
用 axios 這麼處理:
// 請求攔截器
axios.interceptors.request.use(...)
// 響應攔截器
axios.interceptors.response.use(...)
四、具體介面的呼叫
介面呼叫程式碼一般會放在一個檔案中,如 service.js:
export const fetchList = ...
export const fetchDetail = ...
export const createItem = ...
export const updateItem = ...
export const deleteItem = ...
介面呼叫,還有 Loading 狀態管理,防抖,節流,錯誤重試,快取等場景。React 可以用 useRequest,Vue 也有類似的輪子。
五、業務流程
很多業務流程是類似的,可以被複用。比如,管理後臺列表頁的業務流程都類似是這樣的:
進入頁面時,獲取列表資料。
點搜尋按鈕,根據當前的查詢條件,獲取列表資料。
點分頁,獲取指定頁的列表。
自定義 hooks(Vue3 中叫組合式 API) 支援內部的狀態管理和生命週期。因此,可以用 hooks 來封裝業務流程。下面是用 Vue3 的組合式 API 來封裝管理後臺的列表頁的實現:
import { onMounted, reactive, ref, Ref } from 'vue'
export interface Params {
url: string
searchConditions: Record<string, any>
}
interface Return<T> {
searchConditions: Record<string, any>
resetConditions: () => void
pagination: Record<string, any>
fetchList: (isReset: boolean) => void
list: Ref<T[]>
isLoading: Ref<boolean>
}
function useList<T extends Record<string, any>> ({
url,
searchConditions: initCondition
}: Params): Return<T> {
const searchConditions = reactive({...initCondition})
const pagination = reactive({
pageSize: 10
})
const list = ref<T[]>([]) as Ref<T[]>
const isLoading = ref(false) as Ref<boolean>
// isReset 為 true 表示搜第一頁。
const fetchList = (isReset: boolean = false): void => ...
// 進入頁面
onMounted(() => {
fetchList()
})
return {
searchConditions,
pagination,
fetchList,
list,
isLoading,
}
}
export default useList
推薦個 hooks 工具庫:ahooks。Vue 版:ahooks-vue。
六、資料
有些資料指會被多個地方用到。如:登入的使用者資訊,許可權資料。
可以用狀態管理庫來管理這些資料。React 狀態管理一般用 Redux,Mobx 或 Context API。 Vue 一般用 Vuex。
七、工具函式
工具函式是與業務無關的。如:格式化日期,生成唯一的 id 等。Lodash 和 moment.js 包含了很多的工具方法。
總結
要寫出可重用的程式碼,本質就是識別和分離出可複用的部分。前端可以從 UI 展示,介面呼叫,業務流程,資料,工具函式 中找出可複用的部分。
程式碼質量的下一層次就是:可重構的程式碼。我會在下一篇文章中介紹。
金偉強往期精彩文章推薦:
聊聊程式碼質量 - 《學得會,抄得走的提升前端程式碼質量方法》前言
程式碼質量第五層 - 只是實現了功能
程式碼質量第四層 - 健壯的程式碼
程式碼質量第三層 - 可讀的程式碼
《雲薦大咖》是騰訊雲加社群精品內容專欄。雲薦官特邀行業佼者,聚焦於前沿技術的落地及理論實踐之上,持續為您解讀雲時代熱點技術、探索行業發展新機。點選一鍵訂閱,我們將為你定期推送精品內容。