研读 Ant Design、Element Plus、Vant、Fusion 等知名组件库的经验,提炼而成的一套关于“如何封装完美组件”的实践准则。无论是开发项目内可复用的业务组件,还是提取跨项目的公共组件,遵循这些原则都有助于提升组件的可用性、可维护性和一致性。希望能与各位开发者交流探讨,共同推动组件设计质量的提升,减少不完善的组件设计。
1. 基础属性透传原则
每个组件都应支持透传 className 与 style 属性。
import classNames from 'classnames';
export interface CommonProps {
/** 自定义类名 */
className?: string;
/** 自定义内敛样式 */
style?: React.CSSProperties;
}
export interface MyInputProps extends CommonProps {
/** 值 */
value: any
}
const MyInput = forwardRef((props: MyInputProps, ref: React.LegacyRef<HTMLDivElement>) => {
const { className, ...rest } = props;
const displayClassName = classNames('chc-input', className);
return (
<div ref={ref} {...rest} className={displayClassName}>
<span></span>
</div>
);
});
export default ChcInput
2. 注释规范原则
所有 Props 属性及 Ref 引用类型均应添加完整的类型注释。
禁止使用 // 注释内容 这类单行注释语法,因为它们在 TypeScript 中无法被类型系统识别,鼠标悬停时不会显示对应说明。
推荐使用 JSDoc 风格注释,常用标注如下:
-
@description属性描述 -
@version标记引入该属性的起始版本 -
@deprecated标识已废弃的属性 -
@default说明默认值
对于面向国际化场景的组件,建议属性描述优先使用英文。
interface MyInputsProps {
/** custom class */
className?: string
/**
* @description Custom inline style
* @version 2.6.0
* @default ''
*/
style?: React.CSSProperties;
/**
* @description Custom title style
* @deprecated 2.5.0 废弃
* @default ''
*/
customTitleStyle?: React.CSSProperties;
}
const test: MyInputsProps = {}
test.className
3. 导出规范原则
-
Props 类型必须导出:组件的 Props 接口或类型应通过
export对外暴露,便于外部引用和类型复用。 -
Ref 类型必须导出:如果组件使用了
useImperativeHandle暴露内部方法,对应的 Ref 类型也应一并导出。 -
组件函数必须具名:组件函数应使用有意义的名称定义,避免使用匿名函数或箭头函数直接导出,以便在调试堆栈和错误信息中准确定位问题组件。
-
默认导出建议:组件一般推荐使用
export default作为默认导出,保持导入使用的简洁性。
// 暴露 MyInputProps 类型
export interface MyInputProps {
....
}
funtion MyInput(props: MyInputProps) {
return <div></div>;
};
// 也可以自己挂载一个组件名称
if (process.env.NODE_ENV !== 'production') {
MyInput.displayName = 'MyInput';
}
export default MyInput