帮你封装react项目中最常用的10个组件(暴躁版)
react最常用的10个封装组件
·
再写一个 React 版本的前端最常用 10 个组件封装,不带虚的,直接上代码 + 暴躁讲解!
🧠 一、为什么你要封装组件?
因为你不是写一次性页面的程序员!
你写的项目要维护、要复用、要团队协作,别每次都要从头写一遍button或input。
封装的目的就是:
- ✅ 提高复用率
- ✅ 统一风格和逻辑
- ✅ 降低耦合度
- ✅ 装逼加分
📦 二、最常用的 React 组件清单(真实业务高频使用)
| 序号 | 组件名称 | 使用场景 |
|---|---|---|
| 1 | BaseButton.js |
所有按钮统一风格 |
| 2 | BaseInput.js |
表单输入框封装 |
| 3 | BaseSelect.js |
下拉选择器 |
| 4 | BaseTable.js |
数据表格展示 |
| 5 | BaseModal.js |
弹窗通用组件 |
| 6 | BaseForm.js |
表单统一布局与校验 |
| 7 | BasePagination.js |
分页组件 |
| 8 | BaseBreadcrumb.js |
面包屑导航 |
| 9 | BaseCard.js |
内容区块容器 |
| 10 | BaseSkeleton.js |
页面骨架屏 |
🔥 三、每个组件都来一波暴躁封装(React 函数组件 + Hooks)
1. ✅ BaseButton.js(统一按钮样式 & loading)
// BaseButton.jsx
import React from 'react';
import './BaseButton.css';
function BaseButton({ text, type = 'default', loading, disabled, onClick }) {
const className = `base-button ${type ? 'base-button--' + type : ''}`;
return (
<button className={className} onClick={onClick} disabled={loading || disabled}>
{loading ? '加载中...' : text}
</button>
);
}
export default BaseButton;
/* BaseButton.css */
.base-button {
padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
}
.base-button--primary {
background-color: #409EFF;
color: white;
}
.base-button--danger {
background-color: #f56c6c;
color: white;
}
💬 老子一句话:按钮你要是每次都写
v-loading,你是想累死吗?React 可没有 v-loading,靠你自己封装!
2. ✅ BaseInput.js(表单输入统一处理)
// BaseInput.jsx
import React from 'react';
import './BaseInput.css';
function BaseInput({ label, placeholder, value, onChange, type = 'text' }) {
return (
<div className="base-input">
{label && <label>{label}</label>}
<input
type={type}
value={value}
onChange={(e) => onChange(e.target.value)}
placeholder={placeholder}
/>
</div>
);
}
export default BaseInput;
/* BaseInput.css */
.base-input input {
width: 100%;
padding: 8px;
margin-top: 4px;
}
💬 老子一句话:输入框你不封装,你是想让表单变成屎山吗?
3. ✅ BaseSelect.js(下拉选择器统一)
// BaseSelect.jsx
import React from 'react';
function BaseSelect({ value, options, onChange }) {
return (
<select value={value} onChange={(e) => onChange(e.target.value)}>
{options.map((option) => (
<option key={option.value} value={option.value}>
{option.label}
</option>
))}
</select>
);
}
export default BaseSelect;
💬 老子一句话:选个值你都写不好,你是想气死产品经理吗?
4. ✅ BaseTable.js(数据表格统一结构)
// BaseTable.jsx
import React from 'react';
import './BaseTable.css';
function BaseTable({ data, columns }) {
return (
<table className="base-table">
<thead>
<tr>
{columns.map((col, index) => (
<th key={index}>{col.label}</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, i) => (
<tr key={i}>
{columns.map((col, j) => (
<td key={j}>
{col.render ? col.render(row) : row[col.prop]}
</td>
))}
</tr>
))}
</tbody>
</table>
);
}
export default BaseTable;
/* BaseTable.css */
.base-table {
width: 100%;
border-collapse: collapse;
}
.base-table th,
.base-table td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
💬 老子一句话:表格你要是每次都重写
<tr>,你是真不怕重复劳动。
5. ✅ BaseModal.js(弹窗通用组件)
// BaseModal.jsx
import React from 'react';
import './BaseModal.css';
function BaseModal({ visible, title, onClose, children }) {
if (!visible) return null;
return (
<div className="base-modal">
<div className="modal-mask" onClick={onClose}></div>
<div className="modal-content">
<h3>{title}</h3>
<button className="close-btn" onClick={onClose}>X</button>
<div className="modal-body">{children}</div>
<div className="modal-footer">
<button onClick={onClose}>取消</button>
<button onClick={() => alert('提交')}>确定</button>
</div>
</div>
</div>
);
}
export default BaseModal;
/* BaseModal.css */
.base-modal .modal-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: white;
padding: 20px;
z-index: 100;
}
.close-btn {
float: right;
margin-top: -20px;
}
💬 老子一句话:弹窗你不封装,你是想让页面炸了?
6. ✅ BaseForm.js(表单统一结构)
// BaseForm.jsx
import React from 'react';
function BaseForm({ onSubmit, onCancel, children }) {
return (
<form onSubmit={onSubmit} className="base-form">
{children}
<div className="form-actions">
<button type="submit">提交</button>
<button type="button" onClick={onCancel}>取消</button>
</div>
</form>
);
}
export default BaseForm;
💬 老子一句话:表单你不统一结构,你是想让你的代码像厕所一样乱?
7. ✅ BasePagination.js(分页组件)
// BasePagination.jsx
import React from 'react';
function BasePagination({ currentPage, totalPages, onPageChange }) {
function prev() {
if (currentPage > 1) onPageChange(currentPage - 1);
}
function next() {
if (currentPage < totalPages) onPageChange(currentPage + 1);
}
return (
<div className="base-pagination">
<button onClick={prev} disabled={currentPage === 1}>
上一页
</button>
<span>第 {currentPage} 页 / 共 {totalPages} 页</span>
<button onClick={next} disabled={currentPage >= totalPages}>
下一页
</button>
</div>
);
}
export default BasePagination;
💬 老子一句话:分页你不封装,你是想把产品经理干哭吗?
8. ✅ BaseBreadcrumb.js(面包屑导航)
// BaseBreadcrumb.jsx
import React from 'react';
function BaseBreadcrumb({ items }) {
return (
<div className="base-breadcrumb">
{items.map((item, index) => (
<span key={index}>
{item}
{index !== items.length - 1 && ' / '}
</span>
))}
</div>
);
}
export default BaseBreadcrumb;
💬 老子一句话:没有面包屑的系统,就像没有地图的迷宫。
9. ✅ BaseCard.js(内容卡片)
// BaseCard.jsx
import React from 'react';
function BaseCard({ title, children }) {
return (
<div className="base-card">
{title && <h3>{title}</h3>}
<div className="card-content">{children}</div>
</div>
);
}
export default BaseCard;
💬 老子一句话:内容区域不封装成 Card,你是想让 UI 看着难受吗?
10. ✅ BaseSkeleton.js(骨架屏)
// BaseSkeleton.jsx
import React from 'react';
import './BaseSkeleton.css';
function BaseSkeleton({ rows = 5 }) {
return (
<div className="base-skeleton">
{Array.from({ length: rows }).map((_, i) => (
<div key={i} className="skeleton-row"></div>
))}
</div>
);
}
export default BaseSkeleton;
/* BaseSkeleton.css */
.base-skeleton {
padding: 16px;
}
.skeleton-row {
height: 20px;
background: #eee;
margin: 10px 0;
animation: pulse 1.5s infinite ease-in-out;
}
@keyframes pulse {
0% { opacity: 0.4; }
50% { opacity: 1; }
100% { opacity: 0.4; }
}
💬 老子一句话:数据没回来前你不给用户看点东西,用户以为你网站挂了。
🧰 四、如何组织这些组件?(老子教你目录结构)
src/
├── components/
│ ├── BaseButton.jsx
│ ├── BaseInput.jsx
│ ├── BaseSelect.jsx
│ ├── BaseTable.jsx
│ ├── BaseModal.jsx
│ ├── BaseForm.jsx
│ ├── BasePagination.jsx
│ ├── BaseBreadcrumb.jsx
│ ├── BaseCard.jsx
│ └── BaseSkeleton.jsx
└── App.jsx
💬 老子一句话:组件不归类,你是想让新人翻文件翻到吐血吗?
🎁 五、老子送你一个自动注册全局组件的方法(React 不支持 Vue 那种 use,但你可以这样搞)
虽然 React 没有 Vue 的 use(),但你可以:
// components/index.js
export { default as BaseButton } from './BaseButton';
export { default as BaseInput } from './BaseInput';
export { default as BaseSelect } from './BaseSelect';
export { default as BaseTable } from './BaseTable';
export { default as BaseModal } from './BaseModal';
export { default as BaseForm } from './BaseForm';
export { default as BasePagination } from './BasePagination';
export { default as BaseBreadcrumb } from './BaseBreadcrumb';
export { default as BaseCard } from './BaseCard';
export { default as BaseSkeleton } from './BaseSkeleton';
然后在你的页面里可以这样引入:
import {
BaseButton,
BaseInput,
BaseTable,
BasePagination
} from '@/components';
🧠 六、老子总结一句话:
这 10 个组件你要是不会封装,你就别写前端了。
😎💥
更多推荐
所有评论(0)