# 自定义字段

> Source: https://strapi.nodejs.cn/cms/features/custom-fields

🌐 Custom Fields

自定义字段通过新的字段类型扩展 Strapi，这些字段在内容类型构建器和内容管理器中表现得像原生字段。本文档中的说明涵盖了通过插件构建或安装字段以及以编程方式注册字段的步骤。

自定义字段通过向内容类型和组件添加新类型的字段来扩展 Strapi 的功能。一旦通过插件创建或添加到 Strapi，自定义字段就可以像内置字段一样在内容类型构建器和内容管理器中使用。

🌐 Custom fields extend Strapi’s capabilities by adding new types of fields to content-types and components. Once created or added to Strapi via plugins, custom fields can be used in the Content-Type Builder and Content Manager just like built-in fields.

**计划**

免费功能

**角色与权限**

无

**激活**

默认可用并已激活

**环境**

在开发和生产环境中均可用

## 配置 {#configuration}

🌐 Configuration

现成的自定义字段可以在 [Marketplace](https://market.strapi.io/?categories=Custom+fields) 中找到。安装后，无需其他配置，即可开始使用它们（参见 [使用方法](#usage)）。

🌐 Ready-made custom fields can be found on the [Marketplace](https://market.strapi.io/?categories=Custom+fields). Once installed these, no other configuration is required, and you can start using them (see [usage](#usage)).

你也可以开发自己的自定义字段。

🌐 You can also develop your own custom field.

### 开发你自己的自定义字段 {#developing-your-own-custom-field}

🌐 Developing your own custom field

虽然推荐的添加自定义字段的方法是通过创建插件，但特定应用的自定义字段也可以在 `src/index` 和 `src/admin/app` 文件中找到的全局 `register` [函数](/cms/configurations/functions) 中注册。

🌐 Though the recommended way to add a custom field is through creating a plugin, app-specific custom fields can also be registered within the global `register` [function](/cms/configurations/functions) found in `src/index` and `src/admin/app` files.

:::note Current limitations

* 自定义字段只能使用插件在 Marketplace 上共享和分发。
* 自定义字段不能为 Strapi 添加新的数据类型，必须使用在 [模型属性](/cms/backend-customization/models#model-attributes) 文档中描述的现有内置 Strapi 数据类型。
* 你也无法修改现有的数据类型。
* Strapi 特有的特殊数据类型（例如关系、媒体、组件或动态区域数据类型）不能在自定义字段中使用。

:::

:::prerequisites

通过插件注册自定义字段需要创建并启用一个插件（参见 [插件开发](/cms/plugins-development/create-a-plugin)）。

🌐 Registering a custom field through a plugin requires creating and enabling a plugin (see [Plugins development](/cms/plugins-development/create-a-plugin)).

:::

自定义字段插件包括服务器和管理面板部分。自定义字段必须在两个部分都注册，才能在 Strapi 的管理面板中使用。

🌐 Custom field plugins include both a server and admin panel part. The custom field must be registered in both parts before it is usable in Strapi's admin panel.

#### 在服务器上注册自定义字段 {#registering-a-custom-field-on-the-server}

🌐 Registering a custom field on the server

Strapi 的服务器需要了解所有自定义字段，以确保使用自定义字段的属性有效。

🌐 Strapi's server needs to be aware of all the custom fields to ensure that an attribute using a custom field is valid.

`strapi.customFields` 对象在 `Strapi` 实例上公开了一个 `register()` 方法。此方法用于在插件的服务器 [注册生命周期](/cms/plugins-development/server-lifecycle#register) 期间在服务器上注册自定义字段。

🌐 The `strapi.customFields` object exposes a `register()` method on the `Strapi` instance. This method is used to register custom fields on the server during the plugin's server [register lifecycle](/cms/plugins-development/server-lifecycle#register).

`strapi.customFields.register()` 通过传递一个对象（或对象数组）以及一些参数，在服务器上注册一个或多个自定义字段。

<details>
<summary>可用于在服务器上注册自定义字段的参数：</summary>

| 参数 | 描述 | 类型 |
| --- |---------------------------------------------------------------------------------------------------------------------------------------------------------| --- |
| `name` | 自定义字段的名称 | `String` |
| `plugin`<br/><br/>(_可选_) | 创建自定义字段的插件名称<br/><br/>❗️ 如果定义了，则管理面板注册的 `pluginId` 值必须与其相同（参见 [在管理面板注册自定义字段](#registering-a-custom-field-in-the-admin-panel)） | `String` |
| `type` | 自定义字段将使用的数据类型 | `String` |
| `inputSize`<br/><br/>(_可选_) | 用于定义管理面板中自定义字段输入宽度的参数 | `Object` |

可选的 `inputSize` 对象，如果指定，必须包含以下所有参数：

🌐 The optional `inputSize` object, when specified, must contain all of the following parameters:

| 参数 | 描述 | 类型 |
| --- | --- | --- |
| `default` | 在管理面板的 12 列网格中，输入字段默认占用的列数。<br/>值可以是 `4`、`6`、`8` 或 `12`。 | `Integer` |
| `isResizable` | 输入是否可以调整大小 | `Boolean` |

</details>

**示例：在服务器上注册一个示例“颜色”自定义字段：**

在以下示例中，`color-picker` 插件是使用 CLI 生成器创建的（参见 [插件开发](/cms/plugins-development/developing-plugins)）：

🌐 In the following example, the `color-picker` plugin was created using the CLI generator (see [plugins development](/cms/plugins-development/developing-plugins)):

```js title="/src/plugins/color-picker/server/register.js"
module.exports = ({ strapi }) => {
strapi.customFields.register({
  name: "color",
  plugin: "color-picker",
  type: "string",
  inputSize: {
    // optional
    default: 4,
    isResizable: true,
  },
});
};
```

```ts title="/src/plugins/color-picker/server/register.ts"

strapi.customFields.register({
  name: "color",
  plugin: "color-picker",
  type: "string",
  inputSize: {
    // optional
    default: 4,
    isResizable: true,
  },
});
};
```

如果你没有使用 CLI 生成器生成插件代码，该自定义字段也可以直接在 `strapi-server.js` 文件中声明：

🌐 The custom field could also be declared directly within the `strapi-server.js` file if you didn't have the plugin code scaffolded by the CLI generator:

```js title="/src/plugins/color-picker/strapi-server.js"
module.exports = {
register({ strapi }) {
  strapi.customFields.register({
    name: "color",
    plugin: "color-picker",
    type: "text",
    inputSize: {
      // optional
      default: 4,
      isResizable: true,
    },
  });
},
};
```

```ts title="/src/plugins/color-picker/strapi-server.ts"

register({ strapi }: { strapi: any }) {
  strapi.customFields.register({
    name: "color",
    plugin: "color-picker",
    type: "text",
    inputSize: {
      // optional
      default: 4,
      isResizable: true,
    },
  });
},
};
```

#### 在管理面板中注册自定义字段 {#registering-a-custom-field-in-the-admin-panel}

🌐 Registering a custom field in the admin panel

:::prerequisites

通过插件注册自定义字段需要创建并启用一个插件（参见 [插件开发](/cms/plugins-development/create-a-plugin)）。

🌐 Registering a custom field through a plugin requires creating and enabling a plugin (see [Plugins development](/cms/plugins-development/create-a-plugin)).

:::

自定义字段必须在 Strapi 的管理面板中注册，才能在内容类型生成器和内容管理器中使用。

🌐 Custom fields must be registered in Strapi's admin panel to be available in the Content-type Builder and the Content Manager.

`app.customFields` 对象在 `StrapiApp` 实例上暴露了一个 `register()` 方法。此方法用于在插件的管理员 [注册生命周期](/cms/plugins-development/admin-panel-api#register) 中注册自定义字段。

🌐 The `app.customFields` object exposes a `register()` method on the `StrapiApp` instance. This method is used to register custom fields in the admin panel during the plugin's admin [register lifecycle](/cms/plugins-development/admin-panel-api#register).

`app.customFields.register()` 通过传递一个带有某些参数的对象（或对象数组）在管理面板中注册一个或多个自定义字段。

<details>
<summary>可用于在服务器上注册自定义字段的参数：</summary>

| 参数 | 描述 | 类型 |
| --- |----------------------------------------------------------------------------------------------------------------------------------------------| --- |
| `name` | 自定义字段名称 | `String` |
| `pluginId`<br/><br/>(_可选_) | 创建自定义字段的插件名称<br/><br/>❗️ 如果已定义，服务器注册时的 `plugin` 值必须与之相同（见 [在服务器上注册自定义字段](#registering-a-custom-field-on-the-server)） | `String` |
| `type` | 自定义字段将使用的现有 Strapi 数据类型<br/><br/>❗️ 不能使用关系、媒体、组件或动态区域。 | `String` |
| `icon`<br/><br/>(_可选_) | 自定义字段的图标 | `React.ComponentType` |
| `intlLabel` | 名称的翻译 | [IntlObject](https://formatjs.io/docs/react-intl/) |
| `intlDescription` | 描述的翻译 | [IntlObject](https://formatjs.io/docs/react-intl/) |
| `components` | 在内容管理器中显示自定义字段所需的组件（参见 [components](#components)） |
| `options`<br/><br/>(_可选_) | 由内容类型构建器使用的选项（参见 [选项](#options)） | `Object` |

</details>

**示例：在管理面板中注册一个示例“颜色”自定义字段：**

在以下示例中，`color-picker` 插件是使用 CLI 生成器创建的（参见 [插件开发](/cms/plugins-development/developing-plugins.md)）:

🌐 In the following example, the `color-picker` plugin was created using the CLI generator (see [plugins development](/cms/plugins-development/developing-plugins.md)):

```jsx title="/src/plugins/color-picker/admin/src/index.js"

register(app) {
  // ... app.addMenuLink() goes here
  // ... app.registerPlugin() goes here

  app.customFields.register({
    name: "color",
    pluginId: "color-picker", // the custom field is created by a color-picker plugin
    type: "string", // the color will be stored as a string
    intlLabel: {
      id: "color-picker.color.label",
      defaultMessage: "Color",
    },
    intlDescription: {
      id: "color-picker.color.description",
      defaultMessage: "Select any color",
    },
    icon: ColorPickerIcon, // don't forget to create/import your icon component
    components: {
      Input: async () =>
        import('./components/Input').then((module) => ({
          default: module.Input,
        })),
    },
    options: {
      // declare options here
    },
  });
},

// ... bootstrap() goes here
};
```

```ts title="/src/plugins/color-picker/admin/src/index.ts"

register(app) {
  // ... app.addMenuLink() goes here
  // ... app.registerPlugin() goes here

  app.customFields.register({
    name: "color",
    pluginId: "color-picker", // the custom field is created by a color-picker plugin
    type: "string", // the color will be stored as a string
    intlLabel: {
      id: "color-picker.color.label",
      defaultMessage: "Color",
    },
    intlDescription: {
      id: "color-picker.color.description",
      defaultMessage: "Select any color",
    },
    icon: ColorPickerIcon, // don't forget to create/import your icon component
    components: {
      Input: async () =>
        import('./components/Input').then((module) => ({
          default: module.Input,
        })),
    },
    options: {
      // declare options here
    },
  });
},

// ... bootstrap() goes here
};
```

##### 组件 {#components}

🌐 Components

`app.customFields.register()` 必须传递一个包含 `Input` React 组件的 `components` 对象，以在内容管理器的编辑视图中使用。

**示例：注册一个输入组件：**

在以下示例中，`color-picker` 插件是使用 CLI 生成器创建的（参见 [插件开发](/cms/plugins-development/developing-plugins.md)）:

🌐 In the following example, the `color-picker` plugin was created using the CLI generator (see [plugins development](/cms/plugins-development/developing-plugins.md)):

```jsx title="/src/plugins/color-picker/admin/src/index.js"

register(app) {
  app.customFields.register({
    // …
    components: {
      Input: async () =>
        import('./components/Input').then((module) => ({
          default: module.Input,
        })),
    },
    // …
  });
},
};
```

```jsx title="/src/plugins/color-picker/admin/src/index.js"

register(app) {
  app.customFields.register({
    // …
    components: {
      Input: async () =>
        import('./components/Input').then((module) => ({
          default: module.Input,
        })),
    },
    // …
  });
},
};
```

<details>
<summary>传递给自定义字段 <code>Input</code> 组件的属性：</summary>

| 属性 | 描述 | 类型 |
| --- | --- | --- |
| `attribute` | 带有自定义字段的属性对象的底层 Strapi 类型和选项 | `{ type: String, customField: String }` |
| `description` | 在 [配置视图](/cms/features/content-manager#edit-view-settings) 中设置的字段描述 | [IntlObject](https://formatjs.io/docs/react-intl/) |
| `placeholder` | 在 [配置视图](/cms/features/content-manager#edit-view-settings) 中设置的字段占位符 | [IntlObject](https://formatjs.io/docs/react-intl/) |
| `hint` | 在 [配置视图](/cms/features/content-manager#edit-view-settings) 中设置的字段描述，以及最小/最大 [验证要求](/cms/backend-customization/models#validations) | `String` |
| `name` | 在内容类型构建器中设置的字段名称 | `String` |
| `intlLabel` | 在内容类型构建器中设置的字段名称或配置视图 | [IntlObject](https://formatjs.io/docs/react-intl/) |
| `onChange` | 输入变化事件的处理程序。`name` 参数引用字段名称。`type` 参数引用底层 Strapi 类型 | `({ target: { name: String value: unknown type: String } }) => void` |
| `contentTypeUID` | 字段所属的内容类型 | `String` |
| `type` | 自定义字段 uid，例如 `plugin::color-picker.color` | `String` |
| `value` | 底层 Strapi 类型期望的输入值 | `unknown` |
| `required` | 该字段是否为必填 | `boolean` |
| `error` | 验证后收到的错误 | [IntlObject](https://formatjs.io/docs/react-intl/) |
| `disabled` | 输入是否被禁用 | `boolean` |

从 Strapi v4.13.0 开始，内容管理器中的字段可以通过 `URLSearchParam` `field` 自动获得焦点。建议你的输入组件被封装在 React 的 [`forwardRef`](https://react.nodejs.cn/reference/react/forwardRef) 方法中；你应将对应的 `ref` 传递给 `input` 元素。

🌐 As of Strapi v4.13.0, fields in the Content Manager can be auto-focussed via the `URLSearchParam` `field`. It's recommended that your input component is wrapped in React's [`forwardRef`](https://react.nodejs.cn/reference/react/forwardRef) method; you should pass the corresponding `ref` to the `input` element.

<br/>
</details>

**示例：自定义文本输入**

在以下示例中，我们提供了一个受控的自定义文本输入。所有输入都应该是受控的，否则它们的数据在保存时将不会被提交。

🌐 In the following example we're providing a custom text input that is controlled. All inputs should be controlled otherwise their data will not be submitted on save.

<Tabs groupId="js-ts">
<TabItem value="js" label="JavaScript">

```jsx title="/src/plugins/<plugin-name>/admin/src/components/Input.js"

const Input = React.forwardRef((props, ref) => {
const { attribute, disabled, intlLabel, name, onChange, required, value } =
  props; // these are just some of the props passed by the content-manager

const { formatMessage } = useIntl();

const handleChange = (e) => {
  onChange({
    target: { name, type: attribute.type, value: e.currentTarget.value },
  });
};

return (
  <label>
    {formatMessage(intlLabel)}
    <input
      ref={ref}
      name={name}
      disabled={disabled}
      value={value}
      required={required}
      onChange={handleChange}
    />
  </label>
);
});

```

<TabItem value="ts" label="TypeScript">

```tsx title="/src/plugins/<plugin-name>/admin/src/components/Input.ts"

const Input = React.forwardRef((props, ref) => {
const { attribute, disabled, intlLabel, name, onChange, required, value } =
  props; // these are just some of the props passed by the content-manager

const { formatMessage } = useIntl();

const handleChange = (e) => {
  onChange({
    target: { name, type: attribute.type, value: e.currentTarget.value },
  });
};

return (
  <label>
    {formatMessage(intlLabel)}
    <input
      ref={ref}
      name={name}
      disabled={disabled}
      value={value}
      required={required}
      onChange={handleChange}
    />
  </label>
);
});

```

:::tip

要详细了解提供给 customFields 的 props 以及它们如何使用，请查看 Strapi 代码库中的 [ColorPickerInput file](https://github.com/strapi/strapi/blob/main/packages/plugins/color-picker/admin/src/components/ColorPickerInput.tsx#L80-L95) 。

:::

##### 选项 {#options}

🌐 Options

`app.customFields.register()` 可以传递一个额外的 `options` 对象，具有以下参数：

<details>
<summary>传递给自定义字段 <code>options</code> 对象的参数：</summary>

| 参数选项 | 描述 | 类型 |
| --- | --- | --- |
| `base` | 在内容类型构建器的字段的 _基础设置_ 选项卡中可用的设置 | `Object` 或 `Array of Objects` |
| `advanced` | 在内容类型构建器的字段的 _高级设置_ 选项卡中可用的设置 | `Object` 或 `Array of Objects` |
| `validator` | 返回对象的验证函数，用于清理输入。使用 [`yup` schema object](https://github.com/jquense/yup/tree/pre-v1)。 | `Function` |

`base` 和 `advanced` 设置都接受一个对象或对象数组，每个对象都是一个设置部分。每个设置部分可以包括：

🌐 Both `base` and `advanced` settings accept an object or an array of objects, each object being a settings section. Each settings section could include:

- 一个 `sectionTitle` 用于将节的标题声明为一个 [IntlObject](https://formatjs.io/docs/react-intl/)
- 以及一个将 `items` 作为对象数组的列表。

`items` 数组中的每个对象可以包含以下参数：

🌐 Each object in the `items` array can contain the following parameters:

| 参数项 | 描述 | 类型 |
| --- | --- | --- |
| `name` | 输入的标签。<br/>必须使用 `options.settingName` 格式。 | `String` |
| `description` | 在内容类型构建器中使用的输入描述 | `String` |
| `intlLabel` | 输入标签的翻译 | [`IntlObject`](https://formatjs.io/docs/react-intl/) |
| `type` | 输入的类型（例如，`select`、`checkbox`） | `String` |

</details>

**示例：为示例“颜色”自定义字段声明选项：**

在以下示例中，`color-picker` 插件是使用 CLI 生成器创建的（参见 [插件开发](/cms/plugins-development/developing-plugins.md)）:

🌐 In the following example, the `color-picker` plugin was created using the CLI generator (see [plugins development](/cms/plugins-development/developing-plugins.md)):

```jsx title="/src/plugins/color-picker/admin/src/index.js"
// imports go here (ColorPickerIcon, pluginId, yup package…)

register(app) {
  // ... app.addMenuLink() goes here
  // ... app.registerPlugin() goes here
  app.customFields.register({
    // …
    options: {
      base: [
        /*
          Declare settings to be added to the "Base settings" section
          of the field in the Content-Type Builder
        */
        {
          sectionTitle: {
            // Add a "Format" settings section
            id: "color-picker.color.section.format",
            defaultMessage: "Format",
          },
          items: [
            // Add settings items to the section
            {
              /*
                Add a "Color format" dropdown
                to choose between 2 different format options
                for the color value: hexadecimal or RGBA
              */
              intlLabel: {
                id: "color-picker.color.format.label",
                defaultMessage: "Color format",
              },
              name: "options.format",
              type: "select",
              value: "hex", // option selected by default
              options: [
                // List all available "Color format" options
                {
                  key: "hex",
                  defaultValue: "hex",
                  value: "hex",
                  metadatas: {
                    intlLabel: {
                      id: "color-picker.color.format.hex",
                      defaultMessage: "Hexadecimal",
                    },
                  },
                },
                {
                  key: "rgba",
                  value: "rgba",
                  metadatas: {
                    intlLabel: {
                      id: "color-picker.color.format.rgba",
                      defaultMessage: "RGBA",
                    },
                  },
                },
              ],
            },
          ],
        },
      ],
      advanced: [
        /*
          Declare settings to be added to the "Advanced settings" section
          of the field in the Content-Type Builder
        */
      ],
      validator: (args) => ({
        format: yup.string().required({
          id: "options.color-picker.format.error",
          defaultMessage: "The color format is required",
        }),
      }),
    },
  });
},
};
```

```tsx title="/src/plugins/color-picker/admin/src/index.ts"
// imports go here (ColorPickerIcon, pluginId, yup package…)

register(app) {
  // ... app.addMenuLink() goes here
  // ... app.registerPlugin() goes here
  app.customFields.register({
    // …
    options: {
      base: [
        /*
          Declare settings to be added to the "Base settings" section
          of the field in the Content-Type Builder
        */
        {
          sectionTitle: {
            // Add a "Format" settings section
            id: "color-picker.color.section.format",
            defaultMessage: "Format",
          },
          items: [
            // Add settings items to the section
            {
              /*
                Add a "Color format" dropdown
                to choose between 2 different format options
                for the color value: hexadecimal or RGBA
              */
              intlLabel: {
                id: "color-picker.color.format.label",
                defaultMessage: "Color format",
              },
              name: "options.format",
              type: "select",
              value: "hex", // option selected by default
              options: [
                // List all available "Color format" options
                {
                  key: "hex",
                  defaultValue: "hex",
                  value: "hex",
                  metadatas: {
                    intlLabel: {
                      id: "color-picker.color.format.hex",
                      defaultMessage: "Hexadecimal",
                    },
                  },
                },
                {
                  key: "rgba",
                  value: "rgba",
                  metadatas: {
                    intlLabel: {
                      id: "color-picker.color.format.rgba",
                      defaultMessage: "RGBA",
                    },
                  },
                },
              ],
            },
          ],
        },
      ],
      advanced: [
        /*
          Declare settings to be added to the "Advanced settings" section
          of the field in the Content-Type Builder
        */
      ],
      validator: (args) => ({
        format: yup.string().required({
          id: "options.color-picker.format.error",
          defaultMessage: "The color format is required",
        }),
      }),
    },
  });
},
};
```

:::tip

Strapi 代码库提供了一个示例，说明如何描述设置对象：查看 [`baseForm.ts`](https://github.com/strapi/strapi/blob/main/packages/core/content-type-builder/admin/src/components/FormModal/attributes/baseForm.ts) 文件中的 `base` 设置，以及 [`advancedForm.ts`](https://github.com/strapi/strapi/blob/main/packages/core/content-type-builder/admin/src/components/FormModal/attributes/advancedForm.ts) 文件中的 `advanced` 设置。基础表单将设置项以内联方式列出，而高级表单则从 [`attributeOptions.js`](https://github.com/strapi/strapi/blob/main/packages/core/content-type-builder/admin/src/components/FormModal/attributes/attributeOptions.js) 文件中获取设置项。

🌐 The Strapi codebase gives an example of how settings objects can be described: check the [`baseForm.ts`](https://github.com/strapi/strapi/blob/main/packages/core/content-type-builder/admin/src/components/FormModal/attributes/baseForm.ts) file for the `base` settings and the [`advancedForm.ts`](https://github.com/strapi/strapi/blob/main/packages/core/content-type-builder/admin/src/components/FormModal/attributes/advancedForm.ts) file for the `advanced` settings. The base form lists the settings items inline but the advanced form gets the items from an [`attributeOptions.js`](https://github.com/strapi/strapi/blob/main/packages/core/content-type-builder/admin/src/components/FormModal/attributes/attributeOptions.js) file.

:::

## 使用 {#usage}

🌐 Usage

<br/>

### 在管理面板中 {#in-the-admin-panel}

🌐 In the admin panel

可以通过从 [Marketplace](/cms/plugins/installing-plugins-via-marketplace) 安装或创建自己的字段来向 Strapi 添加自定义字段。

🌐 Custom fields can be added to Strapi either by installing them from the [Marketplace](/cms/plugins/installing-plugins-via-marketplace) or by creating your own.

一旦添加到 Strapi，自定义字段可以添加到任何内容类型。选择内容类型的字段时，自定义字段会列在 _Custom_ 选项卡中。

🌐 Once added to Strapi, custom fields can be added to any content type. Custom fields are listed in the _Custom_ tab when selecting a field for a content-type.

每种自定义字段类型都可以有基本和高级设置。 [Marketplace](https://market.strapi.io/?categories=Custom+fields) 列出可用的自定义字段，并为每个自定义字段提供专门的文档，包括具体设置。

### 在代码中 {#in-the-code}

🌐 In the code

创建和使用后，自定义字段的定义就像模型架构中的任何其他属性一样。 

🌐 Once created and used, custom fields are defined like any other attribute in the model's schema. 

自定义字段在模型的[属性](/cms/backend-customization/models#model-attributes)中使用 `type: customField` 明确定义。

🌐 Custom fields are explicitly defined in the [attributes](/cms/backend-customization/models#model-attributes) of a model with `type: customField`.

与其他类型的模型定义方式相比，自定义字段的属性还具有以下特性：

🌐 As compared to how other types of models are defined, custom fields' attributes also show the following specificities:

- 自定义字段具有 `customField` 属性。其值充当唯一标识符，用于指示应使用哪个已注册的自定义字段，并遵循以下两种格式之一：

  | 格式               | 来源 |
  |----------------------|------------------|
  | `plugin::plugin-name.field-name` | 自定义字段是通过插件创建的 |
  | `global::field-name` | 自定义字段特定于当前 Strapi 应用，并且是直接在 `register` [函数](/cms/configurations/functions) 中创建的 |

- 自定义字段可以根据注册自定义字段时定义的内容拥有额外的参数（参见[服务器注册](#registering-a-custom-field-on-the-server)和[管理面板注册](#registering-a-custom-field-in-the-admin-panel)）。

**示例：一个简单的 `color` 自定义字段模型定义：**

```json title="/src/api/[apiName]/[content-type-name]/content-types/schema.json"

{
// …
"attributes": {
  "color": { // name of the custom field defined in the Content-Type Builder
    "type": "customField",
    "customField": "plugin::color-picker.color",
    "options": {
      "format": "hex"
    }
  }
}
// …
}
```

:::tip Custom fields for performance

存储结构化 JSON 的自定义字段可以成为深层嵌套关系结构的高性能替代方案。当数据无需独立查询时，将其存储为单个 JSON 字段可以避免昂贵的联接。详见 Strapi 博客上的 [Building High-Performance Strapi Applications](https://strapi.io/blog/building-high-performance-strapi-applications-common-pitfalls-and-best-practices) 。

:::
