字段概述

字段是 Payload 的基本构建模块,了解如何添加或删除字段、更改字段类型、添加钩子、定义访问控制和验证。

字段是 Payload 的基础构建模块。它们定义了将存储在数据库中的文档结构,并自动在管理后台中生成对应的用户界面。

Payload 提供了多种字段类型可供选择,从简单的文本字符串到嵌套数组和区块等。大多数字段会将数据保存到数据库,而有些则仅用于展示。字段可以配置自定义验证、条件逻辑、访问控制、钩子等多种功能。

字段的外观和行为可以无限定制,而不会影响其底层数据结构。通过使用自定义字段组件,字段设计能够承受重大修改甚至完全替换。

要在你的集合或全局配置中配置字段,请使用 fields 属性:

import type { CollectionConfig } from 'payload'

export const Page: CollectionConfig = {
  // ...
  fields: [
    // highlight-line
    // ...
  ],
}

字段类型

Payload 提供了多种内置的字段类型,每种类型都有其独特的属性和行为,决定了它可以接受哪些值、如何在 API 中呈现以及如何在管理面板中渲染。

要配置字段,请在你的集合或全局配置中使用 fields 属性:

import type { CollectionConfig } from 'payload'

export const Page: CollectionConfig = {
  slug: 'pages',
  // highlight-start
  fields: [
    {
      name: 'field',
      type: 'text',
    },
  ],
  // highlight-end
}

提醒: 每个字段都是一个至少包含 type 属性的对象。该属性将字段与其对应的字段类型匹配。更多详情。

Payload 中的字段主要分为三大类:

开始编写字段时,首先确定哪种字段类型最适合你的应用。然后使用所选字段类型的字段选项来编写你的字段。

数据字段

数据字段用于在数据库中存储数据。所有数据字段都有一个 name 属性,这是用于存储字段值的键名。

以下是可用的数据字段类型:

  • Array - 用于重复内容,支持嵌套字段
  • Blocks - 用于基于块的内容,支持嵌套字段
  • Checkbox - 存储布尔值 true/false
  • Code - 渲染代码编辑器界面并存储字符串
  • Date - 渲染日期选择器并存储时间戳
  • Email - 确保值是格式正确的电子邮件地址
  • Group - 将字段嵌套在键控对象中
  • JSON - 渲染 JSON 编辑器界面并存储 JSON 对象
  • Number - 存储数值
  • Point - 用于位置数据,存储几何坐标
  • Radio - 渲染单选按钮组,只允许选择一个值
  • Relationship - 建立与其他集合的关系
  • Rich Text - 渲染完全可扩展的富文本编辑器
  • Select - 渲染下拉/选择列表样式的值选择器
  • Tabs (Named) - 类似于 group,但在选项卡布局中渲染嵌套字段
  • Text - 简单的文本输入框,存储字符串
  • Textarea - 类似于 text,但允许多行输入
  • Upload - 允许本地文件和图片上传

展示型字段

展示型字段不会在数据库中存储数据。它们主要用于在管理面板中组织和展示其他字段,或者添加自定义UI组件。

以下是可用的展示型字段:

虚拟字段

虚拟字段用于显示不存储在数据库中的数据。它们适用于通过钩子等方式在API响应中显示计算值。

以下是可用的虚拟字段:

提示: 没找到需要的内置字段类型?你可以自己构建!通过结合使用字段验证和自定义组件,你可以完全覆盖组件在管理面板中的功能表现,从而有效地创建自己的字段类型。

字段选项

所有字段至少需要type属性。该属性将字段与其对应的字段类型匹配,以确定其在管理面板中的外观和行为。每种字段类型根据其自身类型都有独特的选项集。

要设置字段类型,请在字段配置中使用type属性:

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text', // highlight-line
  name: 'myField',
}

完整的配置选项列表,请参阅每个字段类型的文档。

字段名称

所有数据字段都需要一个name属性。这是用于在数据库中存储和检索字段值的键名。该属性在当前字段的同级字段中必须是唯一的。

要设置字段名称,请在字段配置中使用name属性:

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text',
  name: 'myField', // highlight-line
}

Payload 保留了一些字段名称供内部使用。使用保留字段名称会导致该字段从配置中被清除。

以下字段名称被禁止使用:

  • __v
  • salt
  • hash
  • file

字段级钩子

除了可以在文档级别定义钩子外,你还可以逐个字段定义极其精细的逻辑。

要定义字段级钩子,请在字段配置中使用hooks属性:

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text',
  name: 'myField',
  // highlight-start
  hooks: {
    // ...
  },
  // highlight-end
}

有关字段级钩子的完整详情,请参阅字段钩子文档。

字段级访问控制

除了可以在文档级别定义访问控制外,你还可以逐个字段定义极其精细的权限。

要定义字段级访问控制,请在字段配置中使用access属性:

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text',
  name: 'myField',
  // highlight-start
  access: {
    // ...
  },
  // highlight-end
}

有关字段级访问控制的完整详情,请参阅字段访问控制文档。

默认值

字段可以选择性地预填充初始值。这个功能在 Admin Panel 和 API 请求中都会被使用,用于在 create 或 update 操作期间填充缺失或未定义的字段值。

要设置字段的默认值,可以在 Field Config 中使用 defaultValue 属性:

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text',
  name: 'myField',
  defaultValue: 'Hello, World!', // highlight-line
}

默认值可以定义为静态值或返回值的函数。当 defaultValue 被静态定义时,Payload 的 Database Adapters 会将其应用到数据库模式或模型中。

函数可以使用以下参数属性:

  • user - 已认证的用户对象
  • locale - 当前选择的语言环境字符串
  • req - PayloadRequest 对象

以下是 defaultValue 函数的示例:

import type { Field } from 'payload'

const translation: {
  en: 'Written by'
  es: 'Escrito por'
}

export const myField: Field = {
  name: 'attribution',
  type: 'text',
  // highlight-start
  defaultValue: ({ user, locale, req }) =>
    `${translation[locale]} ${user.name}`,
  // highlight-end
}

提示: 你可以使用异步的 defaultValue 函数,通过 req.payload 从 API 请求或 Local API 获取数据来填充字段。

验证

字段会根据其字段类型和其他字段选项(如 required 或 min 和 max 值约束)自动进行验证。但如有需要,也可以通过提供自定义验证函数来定制或完全替换字段验证逻辑。

要为字段设置自定义验证函数,请在 Field Config 中使用 validate 属性:

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text',
  name: 'myField',
  validate: (value) => Boolean(value) || '此字段为必填项', // highlight-line
}

自定义验证函数应返回 true 或表示错误信息的 string,该信息将显示在 API 响应中。

validate 函数接收以下参数:

参数描述
value待验证字段的值
ctx包含额外数据和上下文的对象。更多详情

验证上下文

ctx 参数包含完整的文档数据、同级字段数据、当前操作以及其他有用信息(如当前认证用户):

import type { Field } from 'payload'

export const MyField: Field = {
  type: 'text',
  name: 'myField',
  // highlight-start
  validate: (val, { user }) =>
    Boolean(user) || '必须登录才能保存此字段',
  // highlight-end
}

ctx 对象中提供了以下额外属性:

Property描述
data包含当前正在编辑的完整 collection 或 global 文档的对象。
siblingData包含仅限该字段同一父级下字段范围内文档数据的对象。
operation根据 UI 操作或 API 调用,值为 create 或 update。
path字段在 schema 中的完整路径,表示为字符串段数组,包括数组索引。例如 ['group', 'myArray', '1', 'textField']。
id当前正在编辑文档的 id。在 create 操作期间 id 为 undefined。
req当前 HTTP 请求对象。包含 payload、user 等。
event根据当前操作,值为 onChange 或 submit。用作性能优化选项。更多详情。

复用默认字段验证

当使用自定义验证函数时,Payload 会用你的函数替代默认验证。但有时你可能只想在默认验证基础上添加自定义逻辑。

要复用默认字段验证,可以在自定义验证函数中调用它们:

import { text } from 'payload/shared'

const field: Field = {
  name: 'notBad',
  type: 'text',
  validate: (val, args) => {
    if (val === 'bad') return 'This cannot be "bad"'
    return text(val, args) // highlight-line
  },
}

以下是所有默认字段验证函数的列表:

import {
  array,
  blocks,
  checkbox,
  code,
  date,
  email,
  group,
  json,
  number,
  point,
  radio,
  relationship,
  richText,
  select,
  tabs,
  text,
  textarea,
  upload,
} from 'payload/shared'

异步字段验证

根据你的需求,自定义验证函数也可以是异步的。这使得向外部服务发起请求或执行其他异步逻辑成为可能。

在编写异步验证函数时,必须考虑性能影响。验证会在字段每次变更时执行,因此它们应该尽可能轻量。如果你需要执行开销较大的验证(如查询数据库),可以考虑使用 ctx 对象中的 event 属性,仅在表单提交时运行验证。

要编写异步验证函数,使用 async 关键字定义你的函数:

import type { CollectionConfig } from 'payload'

export const Orders: CollectionConfig = {
  slug: 'orders',
  fields: [
    {
      name: 'customerNumber',
      type: 'text',
      // highlight-start
      validate: async (val, { event }) => {
        if (event === 'onChange') {
          return true
        }

        // 仅在表单提交时执行开销较大的验证
        const response = await fetch(`https://your-api.com/customers/${val}`)

        if (response.ok) {
          return true
        }

        return '提供的客户编号与我们的记录不匹配。'
      },
      // highlight-end
    },
  ],
}

自定义 ID 字段

所有 Collections 都会自动生成自己的 ID 字段。如果需要,你可以通过向配置提供显式的 ID 字段来覆盖此行为。该字段应为必填字段,或者具有动态生成 ID 的钩子。

要定义自定义 ID 字段,添加一个顶级字段,并将 name 属性设置为 id:

import type { CollectionConfig } from 'payload'

export const MyCollection: CollectionConfig = {
  // ...
  fields: [
    {
      name: 'id', // highlight-line
      required: true,
      type: 'number',
    },
  ],
}

提醒: 自定义 ID 字段只能是 Number 或 Text 类型。类型为 text 的自定义 ID 字段不得包含 / 或 . 字符。

管理选项

你可以通过任何 Field Config 的 admin 属性来自定义 Admin Panel 中字段的外观和行为:

import type { CollectionConfig } from 'payload'

export const CollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      name: 'myField',
      type: 'text',
      admin: {
        // highlight-line
        // ...
      },
    },
  ],
}

以下是可用的选项:

选项描述
condition根据其他字段以编程方式显示/隐藏字段。更多详情。
components所有 Field Components 都可以替换为你定义的自定义组件。
description在字段旁边显示的帮助文本,为编辑者提供更多信息。更多详情。
position通过定义 position: 'sidebar' 来指定字段是否应渲染在侧边栏中。
width限制字段的宽度。可以传递任何基于字符串的值,如像素、百分比等。当字段嵌套在 Row 类型中并可以水平组织时,此属性特别有用。
style注入到字段根元素的 CSS 属性。
className将 CSS 类属性 附加到字段的根 DOM 元素上。
readOnly将字段设置为 readOnly 对 API 没有任何影响,但会禁用管理组件的可编辑性,防止编辑者修改字段值。
disabled如果字段被 disabled,它将完全从 Admin Panel 中省略。
disableBulkEdit将 disableBulkEdit 设置为 true 可防止字段出现在多文档编辑时的选择选项中。对于 UI 字段默认为 true。
disableListColumn将 disableListColumn 设置为 true 可防止字段出现在列表视图列选择器中。
disableListFilter将 disableListFilter 设置为 true 可防止字段出现在列表视图筛选选项中。
hidden将字段转换为 hidden 输入类型。其值仍会随 Admin Panel 中的请求提交,但字段本身对编辑者不可见。

字段描述

字段描述用于向编辑者提供关于字段的额外信息,例如特殊说明。其展示位置因字段类型而异,但通常会以较为低调的样式显示在字段输入框下方。

描述可以通过三种方式配置:

要为字段添加自定义描述,可在 Field Config 中使用 admin.description 属性:

import type { CollectionConfig } from 'payload'

export const MyCollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      name: 'myField',
      type: 'text',
      admin: {
        description: 'Hello, world!', // highlight-line
      },
    },
  ],
}

提醒: 如需使用自定义组件替换字段描述,请使用 admin.components.Description 属性。详情参见。

描述函数

自定义描述也可以定义为函数形式。描述函数在服务器端执行,可以根据用户当前的语言环境来格式化简单的描述。

要为字段添加描述函数,请在 Field Config 中将 admin.description 属性设置为一个函数:

import type { CollectionConfig } from 'payload'

export const MyCollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      name: 'myField',
      type: 'text',
      admin: {
        description: ({ t }) => `${t('Hello, world!')}`, // highlight-line
      },
    },
  ],
}

所有描述函数都会接收以下参数:

参数描述
t用于国际化管理界面的 t 函数。更多详情

注意: 如果你需要在表单中订阅实时更新,请改用描述组件。更多详情。

条件逻辑

你可以通过在每个字段上使用条件逻辑,根据其他字段的状态来显示或隐藏字段。字段的 admin 配置中的 condition 属性接受一个函数,该函数接收以下参数:

参数描述
data当前正在编辑的整个文档数据。
siblingData仅包含与条件字段直接同级的字段数据。
ctx包含关于字段位置和用户的附加信息的对象。

ctx 对象:

属性描述
blockData最近父级块的数据。如果字段不在块内,则为 undefined。
operation表示字段类型当前执行的操作的字符串。
path字段在 schema 中的完整路径,表示为字符串段的数组,包括数组索引。例如 ['group', 'myArray', '1', 'textField']。
user当前已认证的用户对象。

condition 函数应返回一个布尔值,用于控制是否显示该字段。

示例:

{
  fields: [
    {
      name: 'enableGreeting',
      type: 'checkbox',
      defaultValue: false,
    },
    {
      name: 'greeting',
      type: 'text',
      admin: {
        // highlight-start
        condition: (data, siblingData, { blockData, path, user }) => {
          if (data.enableGreeting) {
            return true
          } else {
            return false
          }
        },
        // highlight-end
      },
    },
  ]
}

自定义组件

在Admin Panel中,字段会在三个不同的位置显示:

  • Field - 在编辑视图中渲染的实际表单字段
  • Cell - 在列表视图中渲染的表格单元格组件
  • Filter - 在列表视图中渲染的筛选组件
  • Diff - 在版本差异视图中渲染的差异组件

要替换为自定义的Field Components,可以在Field Config中使用admin.components属性:

import type { CollectionConfig } from 'payload'

export const CollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      // ...
      admin: {
        components: {
          // highlight-line
          // ...
        },
      },
    },
  ],
}

可用的选项如下:

组件描述
Field在编辑视图中渲染的表单字段。更多详情。
Cell在列表视图中渲染的表格单元格。更多详情。
Filter在列表视图中渲染的筛选组件。更多详情。
Label覆盖Field Component的默认标签。更多详情。
Error覆盖Field Component的默认错误提示。更多详情。
Diff覆盖版本差异视图中渲染的默认差异组件。更多详情。
Description覆盖Field Component的默认描述文本。更多详情。
beforeInput一组元素,将被添加到Field Component输入框之前。更多详情。
afterInput一组元素,将被添加到Field Component输入框之后。更多详情。

Field

Field 组件是在编辑视图中实际渲染的表单字段。这是用户在编辑文档时会与之交互的输入控件。

要替换为你自己的 Field 组件,可以在 Field Config 中使用 admin.components.Field 属性:

import type { CollectionConfig } from 'payload'

export const CollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      // ...
      admin: {
        components: {
          Field: '/path/to/MyFieldComponent', // highlight-line
        },
      },
    },
  ],
}

有关如何构建自定义组件的详细信息,请参阅构建自定义组件。

除了替换整个 Field 组件外,你也可以选择性地只替换或插入特定部分,通过使用 Label、 Error、beforeInput 和 afterInput 属性来实现。

默认属性

所有 Field 组件默认接收以下属性:

PropertyDescription
docPreferences包含文档 Preferences 的对象。
field在客户端组件中,这是经过清理的客户端 Field 配置。在服务端组件中,这是原始的 Field 配置。服务端组件还会通过 clientField 属性接收清理后的字段配置(见下文)。
locale字段的语言环境。更多详情。
readOnly布尔值,表示字段是否为只读。
user当前认证用户。更多详情。
validate用于验证字段的函数。
path字符串,表示运行时字段的直接动态路径,例如 myGroup.myArray.0.myField。
schemaPath字符串,表示 Field 配置的直接静态路径,例如 posts.myGroup.myArray.myField。
indexPath连字符分隔的字符串,表示字段在最近的命名祖先字段中的路径,例如 0-0。

除了上述属性外,所有服务端组件还会接收以下属性:

PropertyDescription
clientField可序列化的客户端 Field 配置。
fieldField 配置。
data当前正在编辑的文档。
i18ni18n 对象。
payloadPayload 类。
permissions基于当前认证用户的字段权限。
siblingData字段同级的数据。
user当前认证用户。更多详情。
value渲染时字段的值。
表单值的发送与接收

当你替换 Field 组件时,需要自行处理表单中字段值的发送和接收。

为此,可以从 @payloadcms/ui 导入 useField 钩子,并使用它来管理字段值:

'use client'
import { useField } from '@payloadcms/ui'

export const CustomTextField: React.FC = () => {
  const { value, setValue } = useField() // highlight-line

  return <input onChange={(e) => setValue(e.target.value)} value={value} />
}

完整可用的 React 钩子列表,请参阅 Payload React Hooks 文档。更多帮助信息,请查看构建自定义组件。

TypeScript#field-component-types

在构建自定义字段组件时,可以导入客户端字段属性类型来确保组件的类型安全。每个字段类型都有对应的客户端和服务端组件类型定义。命名惯例是在目标类型前加上字段类型前缀,例如 TextFieldClientComponent:

import type {
  TextFieldClientComponent,
  TextFieldServerComponent,
  TextFieldClientProps,
  TextFieldServerProps,
  // ...以及其他字段类型的定义
} from 'payload'

具体类型导入请参考各个字段类型的文档。

Cell

Cell 组件在列表视图(List View)的表格中渲染,用于表示字段在表格单元格中显示的值。

要替换为你自己的 Cell 组件,可以在 Field Config 中使用 admin.components.Cell 属性:

import type { Field } from 'payload'

export const myField: Field = {
  name: 'myField',
  type: 'text',
  admin: {
    components: {
      Cell: '/path/to/MyCustomCellComponent', // highlight-line
    },
  },
}

所有 Cell 组件都会接收相同的默认字段组件属性,以及以下额外属性:

属性描述
link布尔值,表示该单元格是否应该被包裹在链接中。
onClick当单元格被点击时调用的函数。

关于如何构建自定义组件本身的详细信息,请参阅构建自定义组件。

Filter

Filter 组件是在列表视图(List View)的"筛选依据"下拉菜单中渲染的实际输入元素,用于在构建筛选器时表示该字段。

要替换为你自己的 Filter 组件,可以在 Field Config 中使用 admin.components.Filter 属性:

import type { Field } from 'payload'

export const myField: Field = {
  name: 'myField',
  type: 'text',
  admin: {
    components: {
      Filter: '/path/to/MyCustomFilterComponent', // highlight-line
    },
  },
}

所有自定义 Filter 组件都会接收相同的默认字段组件属性。

关于如何构建自定义组件本身的详细信息,请参阅构建自定义组件。

Label 组件

Label 组件会在任何需要为字段显示标签的地方渲染。它通常用于编辑视图(Edit View),但也可以在列表视图(List View)和其他地方使用。

要替换为你自己的 Label 组件,可以在 Field Config 中使用 admin.components.Label 属性:

import type { Field } from 'payload'

export const myField: Field = {
  name: 'myField',
  type: 'text',
  admin: {
    components: {
      Label: '/path/to/MyCustomLabelComponent', // highlight-line
    },
  },
}

所有自定义 Label 组件都会接收相同的默认字段组件属性。

关于如何构建自定义组件本身的详细信息,请参阅构建自定义组件。

TypeScript#label-component-types

在构建自定义 Label 组件时,你可以导入组件类型以确保组件的类型安全。对于每种字段类型和服务器/客户端环境,都有明确的 Label 组件类型。命名约定是在字段类型后附加 LabelServerComponent 或 LabelClientComponent,例如 TextFieldLabelClientComponent。

import type {
  TextFieldLabelServerComponent,
  TextFieldLabelClientComponent,
  // ...以及其他字段类型的对应类型
} from 'payload'

描述

除了使用描述属性外,你还可以使用自定义组件作为字段描述。这在需要向用户提供更复杂反馈时非常有用,例如渲染动态字段值或其他交互元素。

要为字段添加描述组件,可以在字段配置中使用 admin.components.Description 属性:

import type { CollectionConfig } from 'payload'

export const MyCollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      name: 'myField',
      type: 'text',
      admin: {
        components: {
          Description: '/path/to/MyCustomDescriptionComponent', // highlight-line
        },
      },
    },
  ],
}

所有自定义描述组件都会接收相同的默认字段组件属性。

关于如何构建自定义组件本身的详细信息,请参阅构建自定义组件。

TypeScript#description-component-types

在构建自定义描述组件时,你可以导入组件属性以确保组件的类型安全。每种字段类型和服务器/客户端环境都有明确的描述组件类型。命名约定是在字段类型后追加 DescriptionServerComponent 或 DescriptionClientComponent,例如 TextFieldDescriptionClientComponent。

import type {
  TextFieldDescriptionServerComponent,
  TextFieldDescriptionClientComponent,
  // 其他字段类型以此类推
} from 'payload'

错误组件

Error 组件在字段验证失败时渲染,通常以醒目的样式显示在字段输入框下方。

要替换为你自己的 Error 组件,可以在 Field Config 中使用 admin.components.Error 属性:

import type { Field } from 'payload'

export const myField: Field = {
  name: 'myField',
  type: 'text',
  admin: {
    components: {
      Error: '/path/to/MyCustomErrorComponent', // highlight-line
    },
  },
}

所有 Error 组件都会接收默认字段组件属性。

关于如何构建自定义组件的详细信息,请参阅构建自定义组件。

TypeScript#error-component-types

构建自定义 Error 组件时,可以导入组件类型以确保组件的类型安全。每个字段类型和服务器/客户端环境都有对应的显式类型。命名约定是在字段类型后添加 ErrorServerComponent 或 ErrorClientComponent,例如 TextFieldErrorClientComponent。

import type {
  TextFieldErrorServerComponent,
  TextFieldErrorClientComponent,
  // 其他字段类型同理
} from 'payload'

差异对比组件

Diff 组件在版本差异视图中渲染,仅在使用版本控制的实体中可见。

要替换为你自己的 Diff 组件,可以在 Field Config 中使用 admin.components.Diff 属性:

import type { Field } from 'payload'

export const myField: Field = {
  name: 'myField',
  type: 'text',
  admin: {
    components: {
      Diff: '/path/to/MyCustomDiffComponent', // highlight-line
    },
  },
}

所有 Error 组件都会接收默认字段组件属性。

关于如何构建自定义组件的详细信息,请参阅构建自定义组件。

TypeScript#diff-component-types

在构建自定义差异组件(Diff Components)时,你可以导入组件类型以确保组件的类型安全。每种字段类型和服务端/客户端环境都有明确的组件类型。命名惯例是在字段类型后添加 DiffServerComponent 或 DiffClientComponent,例如 TextFieldDiffClientComponent。

import type {
  TextFieldDiffServerComponent,
  TextFieldDiffClientComponent,
  // 其他字段类型同理
} from 'payload'

afterInput 和 beforeInput

通过这些属性,你可以按照名称所示,在输入元素的前后添加多个组件。当你需要在字段旁边渲染额外元素而不替换整个字段组件时,这非常有用。

要在输入元素前后添加组件,可以在字段配置中使用 admin.components.beforeInput 和 admin.components.afterInput 属性:

import type { CollectionConfig } from 'payload'

export const MyCollectionConfig: CollectionConfig = {
  // ...
  fields: [
    // ...
    {
      name: 'myField',
      type: 'text',
      admin: {
        components: {
          // highlight-start
          beforeInput: ['/path/to/MyCustomComponent'],
          afterInput: ['/path/to/MyOtherCustomComponent'],
          // highlight-end
        },
      },
    },
  ],
}

所有 afterInput 和 beforeInput 组件都会接收相同的默认字段组件属性。

有关如何构建自定义组件的详细信息,请参阅构建自定义组件。

TypeScript

你可以从 payload 包中导入 Payload 的 Field 类型以及其他常见类型。更多详情。

import type { Field } from 'payload'