🧱 如何設計一個“真正可復用”的前端組件?
🔧 一個按鈕可以寫10次,也可以封裝一次復用全場;組件是前端的積木,而設計模式才是組裝它們的說明書。你真的在寫“可復用”組件嗎?
🧠 什么是可復用組件?
所謂“可復用”,不僅是復制粘貼組件這么簡單,而是:
? 能跨多個頁面/模塊使用
? 能被復合、嵌套、組合
? 能支持靈活配置和擴展
? 能隔離內部邏輯,隱藏實現細節
? 能在多個項目中遷移使用(庫化)
🧩 核心原則一:面向配置編程(Props 設計)
以一個彈窗組件為例:
<Modaltitle="提示"visible={visible}onClose={() => setVisible(false)}footer={<CustomFooter />}
/>
? 好的 Props 應該:
特性 | 示例 |
---|---|
🧠 可讀性強 | title="登錄提示" 比 t="登錄" 好 |
🧩 支持組合 | footer 支持傳 JSX 或隱藏 |
🎯 默認值合理 | closable=true 不傳也能用 |
🚀 高擴展性 | beforeClose() 鉤子支持攔截關閉 |
🧩 核心原則二:關注點分離(拆 UI 和邏輯)
避免在組件中同時處理:
- UI 渲染
- 狀態管理
- 數據獲取
- 事件邏輯
? 推薦:UI 組件 + Hook/Composable 分離邏輯
React 示例(Hooks):
function useModal() {const [visible, setVisible] = useState(false);const open = () => setVisible(true);const close = () => setVisible(false);return { visible, open, close };
}
組件層只負責渲染:
<Modal visible={visible} onClose={close} />
Vue 示例(Composable):
export function useModal() {const visible = ref(false);const open = () => (visible.value = true);return { visible, open };
}
🧩 核心原則三:插槽 & Render Props 讓組件更靈活
Vue 中使用 slot
:
<CustomTable><template #toolbar><Button>新增</Button></template>
</CustomTable>
React 中使用 children
或 render props:
<TablerenderToolbar={() => (<Button>新增</Button>)}
/>
插槽 / Render Props 是組件復用的“開放式接口”。
🧩 核心原則四:可組合的組件設計(組合 > 繼承)
一個“組合式”的 Form 組件架構 👇
<Form><Form.Item label="用戶名"><Input /></Form.Item><Form.Item label="密碼"><Input type="password" /></Form.Item>
</Form>
Form
管理上下文(如驗證、收集值)Form.Item
管理 label、錯誤提示Input
專注輸入邏輯
優點:
- ? 結構清晰
- ? 容易插拔/擴展
- ? 內聚邏輯解耦封裝
🔧 技術加持:讓組件更強大的方法
技術 | 作用 |
---|---|
TypeScript 泛型 | 精確 props 類型,支持 IDE 提示 |
事件派發 / 自定義事件 | 組件內向外傳遞操作 |
Context / Provide/Inject | 實現跨層通信 |
組合式函數(Hooks/Composables) | 提取公共邏輯 |
主題系統 / 樣式變量 | 實現定制化風格 |
🧪 示例:一個「超可復用」的 Table 組件設計思路
? 配置式 + 插槽:
<Tablecolumns={[{ title: '名稱', dataIndex: 'name' },{ title: '年齡', dataIndex: 'age', render: val => <Tag>{val}</Tag> },]}dataSource={data}
/>
? 擴展:支持分頁、loading、自定義操作欄、空狀態提示等:
<Tablecolumns={columns}dataSource={data}loading={loading}pagination={{ current: 1, pageSize: 10 }}emptyTip={<Empty description="暫無數據" />}
/>
這樣封裝后,整套表格系統可被復用于幾十個頁面。
?? 不可復用組件的常見“反模式”
反模式 | 問題 |
---|---|
Props 拆得太碎 | 使用復雜,傳值不直觀 |
寫死業務邏輯 | 拖不動、遷不走、復用不了 |
沒有狀態控制出口 | 用戶無法控制內部行為 |
樣式不隔離 | 每次引入就“爆炸” |
接口數據寫死在組件里 | 不通用,只能在一個項目用 |
🧠 總結:可復用組件的五個關鍵特性
- ? 低耦合:功能單一,職責清晰
- ? 高內聚:UI 與狀態適度綁定
- ? 可組合:支持嵌套、插槽、自定義結構
- ? 可配置:props + config 驅動行為
- ? 可擴展:暴露必要事件、方法,便于集成與增強
組件寫得好,維護效率能提升一個維度;寫得亂,整個項目都跟著混亂。
👍 如果你覺得這篇文章有幫助,歡迎點贊、關注、收藏,下一篇為大家帶來《如何打造一個通用表單生成器組件系統》