Form组件源码阅读(一)

136 阅读2分钟

从项目根目录入手,先要找到我们在项目中引入Form组件时,到底引入了哪一部分的代码。

/index.js

在/index.js中,代码如下:

module.exports = require('./components');

module是一个对象,代指整个js文件。而exports属性就是该文件向外暴露的数据。 可见/index.js向外暴露了从/components/index.ts引入的东西。

/components/index.ts

在/components/index.ts中,代码如下:

export { default as Form } from './form';

export { default as Form } from ***export Form from *** 的缩写。

可见我们在写项目时引用的Form组件,就来自/components/form/index.ts文件中。

/components/form/index.ts

在/components/form/index.ts文件中,代码如下:

const Form = InternalForm as CompoundedComponent;
export default Form;

这段代码中,疑问有两个:

  1. 什么是InternalForm
  2. 什么是CompoundedComponent
  • 关于InternalForm部分的代码如下:
import InternalForm from './Form';

由此可见,在项目中我们引入的Form组件实际上就是/components/form/Form.tsx中默认暴露出来的部分, 或称为内部Form。

  • 关于CompoundedComponent部分的代码如下:
type InternalFormType = typeof InternalForm;

type CompoundedComponent = InternalFormType & {
  useForm: typeof useForm;
  useFormInstance: typeof useFormInstance;
  useWatch: typeof useWatch;
  Item: typeof Item;
  List: typeof List;
  ErrorList: typeof ErrorList;
  Provider: typeof FormProvider;

  /** @deprecated Only for warning usage. Do not use. */
  create: () => void;
};

从代码中不难看出,InternalFormType就是原始的内部Form组件类型,而CompoundedComponent复合类型就是在内部Form组件类型中加上了一些会用到的子组件(如Item)、hooks(如useForm)和api(如create)的类型声明。

不光光是类型上的复合,代码中也把相应的子组件、hooks和api绑定到了Form组件上,代码如下:

Form.Item = Item;
Form.List = List;
Form.ErrorList = ErrorList;
Form.useForm = useForm;
Form.useFormInstance = useFormInstance;
Form.useWatch = useWatch;
Form.Provider = FormProvider;
Form.create = () => {
  warning(
    false,
    'Form',
    'antd v4 removed `Form.create`. Please remove or use `@ant-design/compatible` instead.',
  );
};

因为这样的复合,使得我们在项目中能够通过如下形式,引入我们需要使用的部分:

import { Form } from 'antd';
const { Item, useForm } = Form;

回到这两个问题

  1. 什么是InternalForm
  2. 什么是CompoundedComponent

关于CompoundedComponent的部分我们已经搞清楚了,接下来便深入去了解InternalForm