组件设计怎么让他人清楚的应用你部件,换位思考

lxf2023-03-11 07:18:01

写在前面

如果你对某个一个需求场景有自己的理解,想提炼出开发设计了一个非常好用的部件,想开放给其他同学应用,或是乃至放到小区给任何一个人应用,你该会造成下列疑惑:

  • 一个标准的部件是怎样的,在开发过程中需要注意什么?
  • 部件装包全过程是怎么样的,怎样按需加载?
  • 他人应该怎么没有压力的应用我部件?
  • 部件怎样适用同步和异步应用?
  • 如何更好地维护保养单独组件库?
  • ...

基于以上疑惑,让我们一起来这篇文章阅读文章本文

组件设计

怎么让他人清楚的应用你部件,换位思考一下,你一直在应用其他人元件的情况下,怎么样的部件就是你使用起来十分超出预期乃至超出预算的?怎么样的部件使你在使用的时候,充斥着疑问,造成“还不如自己写一个”的念头?

首先让使用人知道自己的元件的基本功能README.md),次之了解如何使用能满足自己要求(props)。

一个好的README.md应该像antdelementUI的官方文档那般,写具体props使用方法,有明确的实例展现,适当的时候应用mock数据信息适用基本上的样式展现。

举例说明(antd):

组件设计怎么让他人清楚的应用你部件,换位思考

此外,第一次开发设计单独部件或是单独组件库,还需要注意什么呢?

清楚的types类型界定&导出来

清楚的定义方法不但可以降低部件应用门坎,也能使部件降低绝大多数js不正确(比如种类不正确,选值为空不正确等)。

export interface BaseButtonProps {
  type?: ButtonType;
  icon?: React.ReactNode; 
  /**
   * Shape of Button
   *
   * @default default // ✅ 种类注解初始值
   */
  shape?: ButtonShape;
  size?: SizeType;
  disabled?: boolean;
  loading?: boolean | { delay?: number };
  prefixCls?: string;
  className?: string;
  ghost?: boolean;
  danger?: boolean;
  block?: boolean;
  children?: React.ReactNode; // ✅ 对外开放扩展槽
}

export type AnchorButtonProps = {
  href: string;
  target?: string;
  onClick?: React.MouseEventHandler<HTMLElement>;
} & BaseButtonProps &
  Omit<React.AnchorHTMLAttributes<any>, 'type' | 'onClick'>;

// ✅ 对外开放原生态props 
export type NativeButtonProps = {
  htmlType?: ButtonHTMLType;
  onClick?: React.MouseEventHandler<HTMLElement>;
} & BaseButtonProps &
  Omit<React.ButtonHTMLAttributes<any>, 'type' | 'onClick'>;

export type ButtonProps = Partial<AnchorButtonProps & NativeButtonProps>;

可扩展性扩展槽(ReactNode)

给予可交易扩展槽,容许交易方应用自定children做进一步拓展。

// 拓展扩展槽
const {iconNode,kids} = props
 let ButtonNode = (
    <button
      {...(rest as NativeButtonProps)}
      type={htmlType}
      className={classes}
      onClick={handleClick}
      disabled={mergedDisabled}
      ref={buttonRef}
    >
      {iconNode}
      {kids}
    </button>
  );

对外开放与消费最底层部件Props

假如你部件都是基于elementUIantd等最底层组件库进行了进一步封装形式,达到更强的订制要求,不要忘记保存最底层元件的原来作用。

  • Props书写:自定Props extends 最底层部件Props(能通过lib独立引进Props类型)
//这里引进只是为了让表述,具体新项目并不是这样,请自行查看有关部件源代码及其文本文档
import { SelectProps } from 'antd/next/types/select';
import { ISelection } from 'antd/lib/hooks/select/hook';
// 界定props
export interface IEmployeeSelectProps
  extends Omit<SelectProps, 'mode' | 'onChange'>,
  Pick<ISelection, 'maxSelection' | 'mode' | 'onChange'> {
    customPropsA?: string[];
    customPropsB?: string[];
    /**
     * 自定义接口
     */
    list?: QueryListInfoType;
    ...
}
  • 怎样接受并交易传到的最底层部件Props解构赋值
// 接受
const { customPropsA, customPropsB, ...rest } = props;

// 交易
 <Select
  {...rest}
  onChange={customPropsA}
  onSearch={customPropsB}
  ...
  />

可控部件和非可控部件

可控部件便是适用被Reactstate掌控的部件,通俗点说,能通过下传valueonChange操纵部件值。同样推算,非可控部件没跟Reactstate关联,只能依靠关联 Ref单边得到部件值(ref.current.value)。

因而,通常来讲,一个实用的公共组件必须适用可控方式和非可控方式,可以满足一般用户的最简使用需求(部件内部结构自身维护保养情况),也可以满足高级用户的定制市场需求(由应用方传到state值与onChange方式)。

这儿建议使用ahooks的useControllableValue,它适用父部件下传state,假如没有下传,则交给部件内控管理状态值

举例说明:

const [visible, onVisibleChange] = useControllableValue(props, {
    trigger: 'onVisibleChange',
    defaultValuePropName: 'defaultVisible',
    valuePropName: 'visible',
  });

款式防护与CSS变量的应用

CSS并没有修饰符定义,引进即全局性起效,但一个款式是不是起到作用由多个要素共同决定(影响程度、优先、款式载入次序)。部件使用人绝对不期待部件层次的款式影响到了全局性款式,为了防止款式矛盾,我们就要对款式进行隔离。

一般来讲,我们将在部件内部使用一个特定作为前缀,比如element-ui应用el-做为作为前缀。

举例说明sass词法:

$css_prefix: $css-prefix: 'abc-module-' !default;
$content-border-color: rgba(159, 183, 249, 0.5);


.#{$css_prefix}button {
  background-color: $content-border-color;
}

如果你想要开发设计是指一组统一样式的组件库,那样建议使用css自变量,也方便外界使用人通过改变css变量类型的形式统一调节散落着网页页面各处的元件的款式设计风格。

部件多语种及其埋点

假如你部件涉及到全球化有关的,或者想要对外开放深入社区,让世界各国的研发里都应用,那样元件的多语种解决是不可缺少的,可以用模板动态性引入变量类型,并且还要设定好默认防贫创意文案。

再者就是曝出埋点,能够让你清晰的看到部件的使用情况,能够更好的帮助自己改善自已的部件,进而让更多人使用这些。

部件导出来方法

部件导出来方法取决于要让应用方怎么使用,假如你是单独独立部件,以在通道文档以这种方式导出来:

import PageProduct from './components/you-module';
export { default as PageProduct } from './components/you-module';
export default PageProduct;
// 导出来必须的types
export type { IProductProps } from './components/you-module'; 

// 交易方应用
import PageProduct  from '部件';

// 独立引进types类型界定
import type IProductProps from '部件';

假如是组件库,要这样导出来:

export { default as PageProduct1 } from './components/you-module1';
export { default as PageProduct2 } from './components/you-module2';

// 交易方应用
import { PageProduct1PageProduct2 } from '组件库';

部件调节

设计阶段也可以使用文本文档专用工具,比如dumivitePress等静态数据网站专用工具,还可以在开发过程中调节,眼见为实。

装包搭建

开发设计结束后,运用封装工具装包搭建形成生产制造文档。

单元测试卷

假如你部件逻辑性十分复杂,依靠多线程数据信息回到有着不同的主要表现,那样最好是加上单元测试卷,确保每一次正式公布以前。一个新的迭代更新也不会影响老作用。单元测试卷建议使用Jest

部件公布

改动package.json环境变量,登录npm账户将部件公布至npm.

// 控制面板会回到下一个小版本信息 如v1.0.1 
npm version patch 
// 再次公布 
npm publish

部件应用

部件在装包搭建的情况下,通过不同的配备就会形成不一样时代的产物,自然也有着不同的引进方法。“同歩引进”就是指交易方立即npm install package ,在工程代码库中以ES Module的形式引进应用。“多线程引进”方法一般根据要求一个单独的js文档来载入并用部件。

通常来讲,假如是单独部件,且并不是首屏强依赖部件,建议使用异步加载方法。假如是组件库,建议使用同歩载入方法,根据ESM词法开展Tree Shaking,完成根据需求引进。

汇总

部件是对我们常用场景下的一些提炼出,是为了给我们能快速开发出自己想要的作用,而不需要再重新开始,因而实用性、扩展性、采用方便快捷简易、完备的API等特征是考量一个部件是不是实用的最主要的指标值。

好啦,这般咱们就完成了对一个部件从研发到公布、再从所使用的全过程,是不是很简易呢?快点开发设计属于你自己的公共组件吧。