每个 Nova 资源都包含一个 fields
方法。此方法返回一个字段数组,通常扩展 Laravel\Nova\Fields\Field
类。Nova 自带多种字段,包括文本输入、布尔值、日期、文件上传、Markdown 等字段。
要向资源添加字段,只需将其添加到资源的 fields
方法即可。通常,可以使用字段的静态 make
方法创建字段。此方法接受多个参数;但是,通常只需传递字段的“可读”名称即可。Nova 会自动将此字符串“蛇形化”以确定基础数据库列
use Laravel\Nova\Fields\ID;
use Laravel\Nova\Fields\Text;
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Text::make('Name')->sortable(),
];
}
如上所述,Nova 将“蛇形命名”字段的可显示名称,以确定底层数据库列。但是,如果需要,可以将列名作为字段的 make
方法的第二个参数传递
Text::make('Name', 'name_column'),
如果字段有 JSON、ArrayObject
或数组强制转换分配给它,可以使用 ->
运算符指定字段内的嵌套属性
Timezone::make('User Timezone', 'settings->timezone'),
通常,你只希望在某些情况下显示字段。例如,通常不需要在资源索引列表中显示 Password
字段。同样,你可能只希望在创建/更新表单中显示 Created At
字段。Nova 使在某些页面上隐藏/显示字段变得轻而易举。
可以使用以下方法根据显示上下文显示/隐藏字段
showOnIndex
showOnDetail
showOnCreating
showOnUpdating
showOnPreview
showWhenPeeking
hideFromIndex
hideFromDetail
hideWhenCreating
hideWhenUpdating
onlyOnIndex
onlyOnDetail
onlyOnForms
exceptOnForms
你可以将任何这些方法链接到字段的定义中,以指示 Nova 应该在何处显示字段
Text::make('Name')->hideFromIndex(),
或者,可以将回调传递给以下方法。
showOnIndex
showOnDetail
showOnCreating
showOnUpdating
showWhenPeeking
hideFromIndex
hideFromDetail
hideWhenCreating
hideWhenUpdating
showOnPreview
onlyOnPreview
对于 show*
方法,如果给定的回调返回 true
,则将显示该字段
Text::make('Name')->showOnIndex(function (NovaRequest $request, $resource) {
return $this->name === 'Taylor Otwell';
}),
对于 hide*
方法,如果给定的回调返回 true
,则将隐藏该字段
Text::make('Name')->hideFromIndex(function (NovaRequest $request, $resource) {
return $this->name === 'Taylor Otwell';
}),
你可以允许一个字段在 窥视资源时可见,方法是在定义字段时调用 showWhenPeeking
方法
Text::make('Name')->showWhenPeeking(),
你还可以定义哪些字段应包含在资源的“预览”模态框中。用户在查看资源的索引时可以通过该模态框显示给定的资源
Text::make('Title')->showOnPreview(),
Markdown::make('Content')->showOnPreview(),
或者,可以将回调传递给 showOnPreview
方法
Markdown::make('Content')->showOnPreview(function (NovaRequest $request, $resource) {
return $request->user()->can('previewContent');
}),
如果您的应用程序需要,您可以为特定显示上下文指定一个单独的字段列表。例如,假设您有一个具有以下字段列表的资源
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
Text::make('First Name'),
Text::make('Last Name'),
Text::make('Job Title'),
];
}
在您的详细信息页面上,您可能希望通过计算字段显示组合名称,然后显示职位。为此,您可以在资源类中添加一个 `fieldsForDetail` 方法,该方法返回一个单独的字段列表,这些字段应该仅显示在资源的详细信息页面上
/**
* Get the fields displayed by the resource on detail page.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fieldsForDetail(NovaRequest $request)
{
return [
Text::make('Name', function () {
return sprintf('%s %s', $this->first_name, $this->last_name);
}),
Text::make('Job Title'),
];
}
可以为各个显示上下文定义的可用方法是
fieldsForIndex
fieldsForDetail
fieldsForInlineCreate
fieldsForCreate
fieldsForUpdate
fieldsForPreview
动态字段方法优先级 :
`fieldsForIndex`、`fieldsForDetail`、`fieldsForInlineCreate`、`fieldsForCreate`、`fieldsForUpdate` 和 `fieldsForPreview` 方法始终优先于 `fields` 方法。
有时您可能希望为您的字段提供一个默认值。Nova 通过 `default` 方法提供此功能,该方法接受一个值或回调。此值将用作资源创建视图中字段的默认输入值
BelongsTo::make('Name')->default($request->user()->getKey()),
Text::make('Uuid')->default(function ($request) {
return Str::orderedUuid();
}),
默认情况下,字段的占位符文本将是其名称。您可以使用 `placeholder` 方法覆盖支持占位符的字段的占位符文本
Text::make('Name')->placeholder('My New Post'),
对于 Nova 为给定资源接收的每个创建或更新请求,每个字段的相应模型属性将在模型持久化到数据库之前自动填充。如有必要,您可以使用 `fillUsing` 方法自定义给定字段的水化行为
Text::make('Name', 'name')
->fillUsing(function ($request, $model, $attribute, $requestAttribute) {
$model->{$attribute} = Str::title($request->input($attribute));
}),
如果您的资源包含许多字段,您的资源“详细信息”页面可能会变得拥挤。出于这个原因,您可以选择将字段组分解到它们自己的“面板”中
您可以通过在资源的 fields
方法中创建一个新的 Panel
实例来完成此操作。每个面板都需要一个名称和属于该面板的一组字段
use Laravel\Nova\Panel;
/**
* Get the fields displayed by the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function fields(NovaRequest $request)
{
return [
ID::make()->sortable(),
Panel::make('Address Information', $this->addressFields()),
];
}
/**
* Get the address fields for the resource.
*
* @return array
*/
protected function addressFields()
{
return [
Text::make('Address', 'address_line_1')->hideFromIndex(),
Text::make('Address Line 2')->hideFromIndex(),
Text::make('City')->hideFromIndex(),
Text::make('State')->hideFromIndex(),
Text::make('Postal Code')->hideFromIndex(),
Country::make('Country')->hideFromIndex(),
];
}
您可以使用 limit
方法限制在面板中显示的字段数量
Panel::make('Profile', [
Text::make('Full Name'),
Date::make('Date of Birth'),
Text::make('Place of Birth'),
])->limit(1),
具有已定义字段限制的面板将显示一个 显示所有字段 按钮,以便允许用户在需要时查看所有已定义字段。
在将字段附加到资源时,您可以使用 sortable
方法来指示可以按给定字段对资源索引进行排序
Text::make('Name', 'name_column')->sortable(),
关系字段
本文档的这一部分仅讨论非关系字段。要了解有关关系字段的更多信息,请查看其文档。
Nova 附带各种字段类型。因此,让我们探索所有可用的类型及其选项
Audio
字段扩展了 文件字段,并接受相同的选项和配置。Audio
字段与 File
字段不同,它将在查看资源时显示底层图像的缩略图预览
use Laravel\Nova\Fields\Audio;
Audio::make('Theme Song'),
默认情况下,Audio
字段允许用户下载链接的文件。要禁用下载,您可以在字段定义中使用 disableDownload
方法
Audio::make('Theme Song')->disableDownload(),
您可以使用 preload
方法设置字段的 preload 属性
Audio::make('Theme Song')->preload('auto'),
Audio::make('Theme Song')->preload(Audio::PRELOAD_METADATA),
文件字段
要了解有关定义文件字段和处理上传的更多信息,请查看全面的 文件字段文档。
Avatar
字段扩展了 图像字段,并接受相同选项和配置
use Laravel\Nova\Fields\Avatar;
Avatar::make('Avatar'),
如果资源包含 Avatar
字段,当在搜索结果中显示资源时,该字段将显示在资源标题旁边
你可以使用 squared
方法来显示图像缩略图,并带有方形边缘。此外,你可以使用 rounded
方法来显示其具有完全圆角的缩略图
Avatar::make('Avatar')->squared(),
Badge
字段可用于在索引和详细信息视图中显示 Resource
的状态
use Laravel\Nova\Fields\Badge;
Badge::make('Status', function () {
return User::statuses[$this->status];
}),
默认情况下,Badge
字段支持四种变体:info
、success
、danger
和 warning
。你可以使用 map
方法定义可能的字段值及其关联的徽章类型
Badge::make('Status')->map([
'draft' => 'danger',
'published' => 'success',
]),
或者,你可以使用 types
方法完全替换内置徽章类型及其关联的 CSS 类。CSS 类可以作为字符串或数组提供
Badge::make('Status')->types([
'draft' => 'font-medium text-gray-600',
'published' => ['font-bold', 'text-green-600'],
]),
如果你只想补充内置徽章类型,而不是覆盖所有徽章类型,你可以使用 addTypes
方法
Badge::make('Status')->addTypes([
'draft' => 'custom classes',
]),
编辑徽章类型
默认情况下,Badge
字段不会显示在资源的编辑或更新页面上。如果你希望修改由 Badge
字段表示的底层值,请结合 onlyOnForms
字段选项定义另一个字段。
如果你想显示带有关联图标的徽章,你可以使用 withIcons
方法指示 Nova 显示图标
Badge::make('Status')->map([
'draft' => 'danger',
'published' => 'success',
])->withIcons(),
如果你想自定义显示 Badge
字段时使用的图标,你可以使用 icons
方法
Badge::make('Status')->map([
'draft' => 'danger',
'published' => 'success',
])->icons([
'danger' => 'exclamation-circle',
'success' => 'check-circle',
]),
如果你想自定义显示的标签,你可以使用 label
方法
Badge::make('Status')->map([
'draft' => 'danger',
'published' => 'success',
])->label(function ($value) {
return __($value);
}),
你可以使用 labels
方法提供标签列表
Badge::make('Status')->map([
'draft' => 'danger',
'published' => 'success',
])->labels([
'draft' => 'Draft',
'published' => 'Published',
]),
Boolean
字段可用于表示数据库中的布尔值/“微小整数”列。例如,假设你的数据库有一个名为 active
的布尔列,你可以像这样将 Boolean
字段附加到你的资源
use Laravel\Nova\Fields\Boolean;
Boolean::make('Active'),
如果你使用除 true
、false
、1
或 0
之外的其他值来表示“真”和“假”,你可以指示 Nova 使用你的应用程序识别的自定义值。要实现这一点,将 trueValue
和 falseValue
方法链接到你的字段定义
Boolean::make('Active')
->trueValue('On')
->falseValue('Off'),
BooleanGroup
字段可用于对一组布尔复选框进行分组,然后将它们作为 JSON 键值存储在它们所代表的数据库列中。你可以通过为每个选项提供一组键和标签来创建 BooleanGroup
字段
use Laravel\Nova\Fields\BooleanGroup;
BooleanGroup::make('Permissions')->options([
'create' => 'Create',
'read' => 'Read',
'update' => 'Update',
'delete' => 'Delete',
]),
用户将看到一组分组的复选框,保存后,这些复选框将转换为 JSON 格式
{
"create": true,
"read": false,
"update": false,
"delete": false
}
在使用此字段类型之前,你应确保底层 Eloquent 属性配置为在你的 Eloquent 模型类中转换为 array
(或等效项)
protected $casts = [
'permissions' => 'array'
];
有时,你可能希望排除 true
或 false
值以避免字段表示混乱。你可以通过在字段定义中调用 hideFalseValues
或 hideTrueValues
方法来实现这一点
BooleanGroup::make('Permissions')->options([
'create' => 'Create',
'read' => 'Read',
'update' => 'Update',
'delete' => 'Delete',
])->hideFalseValues(),
BooleanGroup::make('Permissions')->options([
'create' => 'Create',
'read' => 'Read',
'update' => 'Update',
'delete' => 'Delete',
])->hideTrueValues(),
如果底层字段为空,Nova 将显示“无数据”。你可以使用 noValueText
方法自定义此文本
BooleanGroup::make('Permissions')->options([
'create' => 'Create',
'read' => 'Read',
'update' => 'Update',
'delete' => 'Delete',
])->noValueText('No permissions selected.'),
Code
字段在你的 Nova 管理面板中提供了一个漂亮的代码编辑器。通常,代码字段应附加到 TEXT
数据库列
use Laravel\Nova\Fields\Code;
Code::make('Snippet'),
你还可以将 Code
字段附加到 JSON
数据库列。默认情况下,该字段将值显示为 JSON 字符串。你可以根据应用程序的需要将底层 Eloquent 属性转换为 array
、collection
、object
或 json
use Laravel\Nova\Fields\Code;
Code::make('Options')->json(),
索引中的代码字段
默认情况下,Nova 永远不会在资源索引列表中显示 Code
字段。
如果你打算仅使用给定的 Code
字段实例来编辑 JSON,你可以将 json
方法链接到你的字段定义
Code::make('Options')->json(),
代码字段 JSON 验证
Nova 不会自动将 json
验证规则应用于 Code
字段。如果你希望应用此规则,则必须在验证期间手动指定它。
你可以使用 language
方法自定义 Code
字段的语言语法高亮
Code::make('Snippet')->language('php'),
Code
字段当前支持的语言为
dockerfile
htmlmixed
javascript
markdown
nginx
php
ruby
sass
shell
sql
twig
vim
vue
xml
yaml-frontmatter
yaml
Color
字段使用 HTML5 color
输入元素生成颜色选择器
use Laravel\Nova\Fields\Color;
Color::make('Color', 'label_color'),
Country
字段生成一个 Select
字段,其中包含世界各国/地区的列表。该字段将存储国家/地区的相应两位代码
use Laravel\Nova\Fields\Country;
Country::make('Country', 'country_code'),
Currency
字段生成一个 Number
字段,该字段使用 brick/money
PHP 包自动设置格式。Nova 将使用 USD
作为默认货币;但是,可以通过修改 nova.currency
配置值来更改此设置
use Laravel\Nova\Fields\Currency;
Currency::make('Price'),
你可以使用 currency
方法逐字段覆盖货币
Currency::make('Price')->currency('EUR'),
先决条件
需要 ext-intl
PHP 扩展才能显示格式化的货币。或者,你可以安装 symfony/polyfill-intl-icu
Composer 包,该包支持“en”语言环境。
你可以使用 min
、max
和 step
方法在生成的 input
控件上设置相应的属性
Currency::make('price')->min(1)->max(1000)->step(0.01),
货币步长限制
如果你计划使用 step
方法自定义货币“步长”金额,则应确保始终在 currency
、asMinorUnits
和 asMajorUnits
方法之后调用 step
方法。在 step
方法之后调用这些方法将覆盖 step
方法的行为。
该字段的语言环境将遵循应用程序 app.locale
配置值中的值。你可以通过向 locale
方法提供语言环境代码来覆盖此行为
Currency::make('Price')->locale('fr'),
Date
字段可用于存储日期值(不含时间)。有关 Nova 中的日期和时区的更多信息,请查看其他 日期/时区文档
use Laravel\Nova\Fields\Date;
Date::make('Birthday'),
DateTime
字段可用于存储日期时间值。有关 Nova 中的日期和时区的更多信息,请查看其他 日期/时区文档
use Laravel\Nova\Fields\DateTime;
DateTime::make('Updated At')->hideFromIndex(),
Email
字段可用于在索引和详细视图中显示带有 mailto:
链接的列
use Laravel\Nova\Fields\Email;
Email::make(),
Email::make('Customer Email', 'customer_email'),
要了解有关定义文件字段和处理上传的更多信息,请参阅全面的 文件字段文档。
use Laravel\Nova\Fields\File;
File::make('Attachment'),
Gravatar
字段不对应于应用程序数据库中的任何列。相反,它将显示与其关联的模型的“Gravatar”图像。
默认情况下,Gravatar URL 将根据模型的 email
列的值生成。但是,如果用户的电子邮件地址未存储在 email
列中,则可以将自定义列名称传递给字段的 make
方法
use Laravel\Nova\Fields\Gravatar;
// Using the "email" column...
Gravatar::make(),
// Using the "email_address" column...
Gravatar::make('Avatar', 'email_address'),
可以使用 squared
方法显示具有方形边缘的图像缩略图。此外,可以使用 rounded
方法显示具有完全圆形边缘的图像
Gravatar::make('Avatar', 'email_address')->squared(),
Heading
字段不对应于应用程序数据库中的任何列。它用于在表单中显示横幅,并且可以作为长字段列表的分隔符
use Laravel\Nova\Fields\Heading;
Heading::make('Meta'),
如果需要在 Heading
字段中呈现 HTML 内容,则可以在定义字段时调用 asHtml
方法
Heading::make('<p class="text-danger">* All fields are required.</p>')->asHtml(),
标题和索引页
Heading
字段会自动从资源索引页中隐藏。
Hidden
字段可用于传递用户无需更改但保存资源所需的任何值
Hidden::make('Slug'),
Hidden::make('Slug')->default(Str::random(64)),
与 默认值 结合使用时,Hidden
字段可用于将相关 ID 之类的内容传递给表单
Hidden::make('User', 'user_id')->default(function ($request) {
return $request->user()->id;
}),
ID
字段表示资源数据库表的自增主键。通常,定义的每个 Nova 资源都应包含一个 ID
字段。默认情况下,ID
字段假定底层数据库列名为 id
;但是,如果需要,可以将列名作为第二个参数传递给 make
方法
use Laravel\Nova\Fields\ID;
ID::make(),
ID::make('ID', 'id_column'),
如果应用程序包含非常大的整数 ID,则可能需要使用 asBigInt
方法才能使 Nova 客户端正确呈现整数
ID::make()->asBigInt(),
ID 字段
每个资源应仅配置一个 ID
字段。
Image
字段扩展了 文件字段,并接受相同的选项和配置。Image
字段与 File
字段不同,在查看资源时将显示底层图像的缩略图预览
use Laravel\Nova\Fields\Image;
Image::make('Photo'),
默认情况下,Image
字段允许用户下载链接的文件。要禁用下载,您可以在字段定义中使用 disableDownload
方法
Image::make('Photo')->disableDownload(),
您可以使用 squared
方法以方形边缘显示图像的缩略图。此外,您可以使用 rounded
方法以完全圆形的边缘显示其缩略图。
文件字段
要了解有关定义文件字段和处理上传的更多信息,请查看全面的 文件字段文档。
KeyValue
字段提供了一个便捷的界面,用于编辑存储在 JSON
列类型中的平面键值数据。例如,您可以在名为 meta
的 JSON 列类型 中存储个人资料信息
use Laravel\Nova\Fields\KeyValue;
KeyValue::make('Meta')->rules('json'),
鉴于上述字段定义,Nova 将呈现以下界面
您可以在定义字段时调用 keyLabel
、valueLabel
和 actionText
方法,以自定义组件中使用的文本值。actionText
方法自定义“添加行”按钮文本
KeyValue::make('Meta')
->keyLabel('Item')
->valueLabel('Label')
->actionText('Add Item'),
KeyValue 字段和索引页面
默认情况下,Nova 绝不会在资源索引列表中显示 KeyValue
字段。
如果您想禁用用户编辑字段键的能力,可以使用 disableEditingKeys
方法来实现。使用 disableEditingKeys
方法禁用编辑键将自动禁用添加行
KeyValue::make('Meta')->disableEditingKeys(),
您还可以通过将 disableAddingRows
方法链接到字段定义,来移除用户向字段添加新行能力
KeyValue::make('Meta')->disableAddingRows(),
此外,您可能还希望移除用户删除字段中现有行能力。您可以在定义字段时调用 disableDeletingRows
方法来实现
KeyValue::make('Meta')->disableDeletingRows(),
Markdown
字段为其底层 Eloquent 属性提供了一个所见即所得的 Markdown 编辑器。通常,此字段将对应数据库中的 TEXT
列。Markdown
字段将把原始 Markdown 文本存储在关联的数据库列中
use Laravel\Nova\Fields\Markdown;
Markdown::make('Biography'),
默认情况下,Markdown 字段在查看资源的详细信息页面时不会显示其内容。相反,内容将隐藏在“显示内容”链接后面,单击该链接时将显示该字段的内容。您可以通过对字段本身调用 alwaysShow
方法来指定 Markdown 字段应始终显示其内容
Markdown::make('Biography')->alwaysShow(),
Markdown 字段使用 league/commonmark
包来解析 Markdown 内容。默认情况下,它使用类似于 GitHub Flavored Markdown 的解析策略,该策略不允许 Markdown 内容中包含某些 HTML。但是,您可以使用 preset
方法更改解析策略。目前,以下内置预设为 default
、commonmark
和 zero
Markdown::make('Biography')->preset('commonmark'),
使用 preset
方法,您可以注册和使用自定义预设实现
use Illuminate\Support\Str;
use Laravel\Nova\Fields\Markdown;
use Laravel\Nova\Fields\Markdown\MarkdownPreset;
Markdown::make('Biography')->preset('github', new class implements MarkdownPreset {
/**
* Convert the given content from markdown to HTML.
*
* @param string $content
* @return string
*/
public function convert(string $content)
{
return Str::of($content)->markdown([
'html_input' => 'strip',
]);
}
}),
如果您希望允许用户将照片拖放到 Markdown
字段中,则可以将 withFiles
方法链接到字段的定义上。在调用 withFiles
方法时,您应该传递 文件系统磁盘 的名称,照片应存储在该磁盘上
use Laravel\Nova\Fields\Markdown;
Markdown::make('Biography')->withFiles('public'),
Nova 将定义两个数据库表来存储待处理和已持久化的 Field
上传。在安装期间运行 Nova 的迁移时,将自动创建这两个表:nova_pending_field_attachments
和 nova_field_attachments
。
最后,在您的 routes/console.php
文件中,您应该注册一个 每日计划任务,以从待处理附件表和存储中清除任何过时的附件。为了方便起见,Laravel Nova 提供了完成此任务所需的作业实现
use Illuminate\Support\Facades\Schedule;
use Laravel\Nova\Fields\Attachments\PruneStaleAttachments;
Schedule::call(new PruneStaleAttachments)->daily();
MultiSelect
字段提供一个 Select
字段,允许多个选择选项。此字段与转换为 array
或等效项的模型属性很好地配对
use Laravel\Nova\Fields\MultiSelect;
MultiSelect::make('Sizes')->options([
'S' => 'Small',
'M' => 'Medium',
'L' => 'Large',
]),
在资源索引和详细信息页面上,将显示 MultiSelect
字段的“键”值。如果您希望改为显示标签值,则可以在定义字段时调用 displayUsingLabels
方法
MultiSelect::make('Size')->options([
'S' => 'Small',
'M' => 'Medium',
'L' => 'Large',
])->displayUsingLabels(),
您还可以通过提供包含键和 label
/ group
对的数组结构,按组显示多选选项
MultiSelect::make('Sizes')->options([
'MS' => ['label' => 'Small', 'group' => "Men's Sizes"],
'MM' => ['label' => 'Medium', 'group' => "Men's Sizes"],
'WS' => ['label' => 'Small', 'group' => "Women's Sizes"],
'WM' => ['label' => 'Medium', 'group' => "Women's Sizes"],
])->displayUsingLabels(),
Number
字段提供一个 input
控件,其 type
属性为 number
use Laravel\Nova\Fields\Number;
Number::make('price'),
您可以使用 min
、max
和 step
方法在生成的 input
控件上设置相应的 HTML 属性
Number::make('price')->min(1)->max(1000)->step(0.01),
您还可以允许任意精度的十进制值
Number::make('price')->min(1)->max(1000)->step('any'),
Password
字段提供一个 input
控件,其 type
属性为 password
use Laravel\Nova\Fields\Password;
Password::make('Password'),
如果传入的密码字段为空,则 Password
字段将自动保留当前存储在数据库中的密码。因此,典型的密码字段定义可能如下所示
use Illuminate\Validation\Rules;
Password::make('Password')
->onlyOnForms()
->creationRules('required', Rules\Password::defaults())
->updateRules('nullable', Rules\Password::defaults()),
PasswordConfirmation
字段提供一个输入,可用于确认另一个 Password
字段。此字段仅显示在表单上,并且不会尝试给 Eloquent 模型上的底层属性注入数据
PasswordConfirmation::make('Password Confirmation'),
使用此字段时,您应该在相应的 Password
字段上定义适当的验证规则
Password::make('Password')
->onlyOnForms()
->creationRules('required', Rules\Password::defaults(), 'confirmed')
->updateRules('nullable', Rules\Password::defaults(), 'confirmed'),
PasswordConfirmation::make('Password Confirmation'),
Select
字段可用于生成下拉选择菜单。可以使用 options
方法定义 Select
菜单的选项
use Laravel\Nova\Fields\Select;
Select::make('Size')->options([
'S' => 'Small',
'M' => 'Medium',
'L' => 'Large',
]),
在资源索引和详细信息页面上,将显示 Select
字段的“键”值。如果您希望改为显示标签,则可以使用 displayUsingLabels
方法
Select::make('Size')->options([
'S' => 'Small',
'M' => 'Medium',
'L' => 'Large',
])->displayUsingLabels(),
您还可以通过提供包含键和 label
/ group
对的数组结构,以组的形式显示 Select
选项
Select::make('Size')->options([
'MS' => ['label' => 'Small', 'group' => 'Men Sizes'],
'MM' => ['label' => 'Medium', 'group' => 'Men Sizes'],
'WS' => ['label' => 'Small', 'group' => 'Women Sizes'],
'WM' => ['label' => 'Medium', 'group' => 'Women Sizes'],
])->displayUsingLabels(),
如果您需要对 Select
字段选项的生成有更多控制,您可以向 options
方法提供一个闭包
Select::make('Size')->options(function () {
return array_filter([
Size::SMALL => Size::MAX_SIZE === SIZE_SMALL ? 'Small' : null,
Size::MEDIUM => Size::MAX_SIZE === SIZE_MEDIUM ? 'Medium' : null,
Size::LARGE => Size::MAX_SIZE === SIZE_LARGE ? 'Large' : null,
]);
}),
有时,能够搜索或筛选 Select
字段中可用的选项列表会很方便。您可以通过在字段上调用 searchable
方法来启用此功能
Select::make('Size')->searchable()->options([
'S' => 'Small',
'M' => 'Medium',
'L' => 'Large',
])->displayUsingLabels(),
将选择字段标记为 searchable
后,Nova 将显示一个 input
字段,允许您根据其标签筛选选项列表
有时您可能需要根据另一个字段的内容生成一个唯一的人类可读标识符,例如在为博客文章标题生成“slug”时。您可以使用 Slug
字段自动生成这些“slug”
Slug::make('Slug')->from('Title'),
默认情况下,该字段会将诸如“我的博客文章”这样的字符串转换为诸如“my-blog-post”这样的 slug。如果您希望该字段使用下划线而不是破折号,您可以使用 separator
方法定义您自己的自定义“分隔符”
Slug::make('Slug')->from('Title')->separator('_'),
Sparkline
字段可用于在资源的索引或详情页面上显示一个小的折线图。提供给 Sparkline
的数据可以通过 array
、callable
(返回一个数组)或 Trend
指标类的实例提供
// Using an array...
Sparkline::make('Post Views')->data([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]),
// Using a callable...
Sparkline::make('Post Views')->data(function () {
return json_decode($this->views_data);
}),
如果 Sparkline
字段所需的数据需要复杂的数据库查询来计算,您可能希望将数据检索封装在 趋势指标 中,然后可以将其提供给 Sparkline
字段
Sparkline::make('Post Views')->data(new PostViewsOverTime($this->id)),
在上面的示例中,我们向指标的构造函数提供了帖子的 id
。此值将成为趋势指标中可用的请求的 resourceId
属性。例如,在指标中,我们可以通过 $request->resourceId
访问此帖子 ID
return $this->countByDays(
$request,
PostView::where('post_id', '=', $request->resourceId)
);
默认范围
通过趋势指标向 Sparkline
字段提供数据时,Sparkline
字段将始终使用指标的 ranges
方法中定义的第一个范围。
如果条形图更适合您的数据,您可以在定义字段时调用 asBarChart
方法
Sparkline::make('Post Views')
->data([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
->asBarChart(),
默认情况下,Sparkline
将显示在资源的详细信息页面上。你可以使用 height
和 width
方法自定义图表的大小
Sparkline::make('Post Views')
->data([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
->height(200)
->width(600),
Status
字段可用于显示“进度状态”列。在内部,Nova 使用 Status
字段来指示排队操作的当前状态(等待、运行或完成)。但是,你可以根据需要自由地将此字段用于自己的目的
loadingWhen
和 failedWhen
方法可用于指示字段哪些单词表示“加载”状态,哪些单词表示“失败”状态。在此示例中,我们将指示数据库列值 waiting
或 running
应显示“加载”指示器
use Laravel\Nova\Fields\Status;
Status::make('Status')
->loadingWhen(['waiting', 'running'])
->failedWhen(['failed']),
随着资源类不断增多,你可能会发现将字段组合在一起以简化你的索引和详细信息视图很有用。Stack
字段允许你以垂直方向显示 BelongsTo
、Text
和其他字段
Stack::make('Details', [
Text::make('Name'),
Text::make('Slug')->resolveUsing(function () {
return Str::slug(optional($this->resource)->name);
}),
]),
Stack
字段不会显示在表单中,并且仅用于在索引和详细信息资源视图中堆叠文本行。
为了更好地控制 Stack
中各个字段的显示方式,你可以使用 Line
字段,它提供了控制行文本显示的方法。Line
字段提供了以下表示方法
asHeading
asSubTitle
asSmall
asBase
除了 Line
字段的表示方法外,你还可以将任何其他 Tailwind 类传递给字段以自定义 Line
的外观
Stack::make('Details', [
Line::make('Title')->extraClasses('italic font-medium text-80'),
]),
除了将 BelongsTo
、Text
和 Line
字段传递到 Stack
字段外,还可以传递一个闭包。闭包的结果将自动转换为 Line
实例
Stack::make('Details', [
Line::make('Name')->asHeading(),
fn () => optional($this->resource)->position
]),
Tag
字段允许使用标签选择界面搜索和附加 BelongsToMany
关系。此字段对于向用户添加角色、标记文章、向书籍分配作者以及其他类似场景非常有用
use Laravel\Nova\Fields\Tag;
Tag::make('Tags'),
Tag
字段将显示在索引视图的下拉菜单中
可以通过在字段上调用 withPreview
方法,指示 Tag
字段允许预览标签的关系。这将在模态窗口中显示相关资源的预览详细信息
use Laravel\Nova\Fields\Tag;
Tag::make('Tags')->withPreview(),
可以将标签显示为列表,而不是将它们显示为内联组
use Laravel\Nova\Fields\Tag;
Tag::make('Tags')->displayAsList(),
这允许使用标题、副标题和已配置的图像字段显示标签
为方便起见,当在资源创建或更新页面上显示 Tag
字段时,可以通过模态窗口内联创建相关资源,而无需离开创建/更新页面
要启用此功能,请在定义字段时调用 showCreateRelationButton
方法
use Laravel\Nova\Fields\Tag;
Tag::make('Tags')->showCreateRelationButton(),
可以使用 modalSize
方法调整模态窗口的大小
// Can be "sm", "md", "lg", "xl", "2xl", "3xl", "4xl", "5xl", "6xl", "7xl".
Tag::make('Tags')->showCreateRelationButton()->modalSize('7xl'),
为了让现有标签更易于发现,可以在定义字段时通过调用 preload
方法,在资源创建或更新期间向用户显示所有可用标签
Tag::make('Tags')->preload(),
Text
字段提供了一个 input
控件,其 type
属性为 text
use Laravel\Nova\Fields\Text;
Text::make('Name'),
可以通过设置字段上的任何属性进一步自定义文本字段。这可以通过调用 withMeta
方法并提供包含 HTML 属性的键/值对的 extraAttributes
数组来完成
Text::make('Name')->withMeta([
'extraAttributes' => [
'placeholder' => 'David Hemphill',
],
]),
要在键入 Text
字段时提供自动完成建议,可以在定义字段时调用 suggestions
方法。suggestions
方法应返回一个建议的 array
Text::make('Name')->required()
->suggestions([
'David Hemphill',
'Taylor Otwell',
'James Brooks',
]),
要将 Text
字段格式化为链接,可以在定义字段时调用 asHtml
方法
Text::make('Twitter Profile', function () {
$username = $this->twitterUsername;
return "<a href='https://twitter.com/{$username}'>@{$username}</a>";
})->asHtml(),
有时你可能希望将字段的值复制到系统剪贴板以粘贴到其他地方。你可以在资源的详细视图中通过在 Text
字段上调用 copyable
方法来启用此功能
Text::make('Twitter Profile')->copyable(),
maxlength
你可能希望向用户表明 Text
字段的内容应保持在一定长度内。你可以通过在字段上使用 maxlength
方法来实现此目的
use Laravel\Nova\Fields\Text;
Text::make('Name')->maxlength(250),
Nova 将显示字段的最大长度以及字符计数器。但是,Nova 不会强制执行最大长度。要指示 Nova 强制执行限制,你可以在字段上调用 enforceMaxlength
方法
use Laravel\Nova\Fields\Text;
Text::make('Name')->maxlength(250)->enforceMaxlength(),
Textarea
字段提供了一个 textarea
控件
use Laravel\Nova\Fields\Textarea;
Textarea::make('Biography'),
默认情况下,文本域字段在查看资源的详细信息页面时不会显示其内容。相反,字段的内容将隐藏在“显示内容”链接后面,单击该链接时将显示内容。但是,如果你愿意,你可以通过在字段上调用 alwaysShow
方法来指定 Textarea
字段应始终显示其内容
Textarea::make('Biography')->alwaysShow(),
你可以通过在字段上调用 rows
方法来指定 Textarea
高度
Textarea::make('Excerpt')->rows(3),
可以通过设置字段上的任何属性进一步自定义 Textarea
字段。这可以通过调用 withMeta
方法并提供包含 HTML 属性的键/值对的 extraAttributes
数组来完成
Textarea::make('Excerpt')->withMeta(['extraAttributes' => [
'placeholder' => 'Make it less than 50 characters']
]),
maxlength
你可能希望向用户表明 Textarea
字段的内容应保持在一定长度内。你可以通过在该字段上使用 maxlength
方法来实现此目的
use Laravel\Nova\Fields\Textarea;
Textarea::make('Name')->maxlength(250),
Nova 将显示字段的最大长度以及字符计数器。但是,Nova 不会强制执行最大长度。要指示 Nova 强制执行限制,你可以在字段上调用 enforceMaxlength
方法
use Laravel\Nova\Fields\Textarea;
Textarea::make('Name')->maxlength(250)->enforceMaxlength(),
Timezone
字段生成一个 Select
字段,其中包含世界时区列表
use Laravel\Nova\Fields\Timezone;
Timezone::make('Timezone'),
Trix
字段为其关联字段提供一个 Trix 编辑器。通常,此字段将对应于数据库中的 TEXT
列。Trix
字段将在关联的数据库列中存储其对应的 HTML
use Laravel\Nova\Fields\Trix;
Trix::make('Biography'),
默认情况下,Trix 字段在资源详情页上查看资源时不会显示其内容。相反,内容将隐藏在“显示内容”链接后面,单击该链接时将显示字段的内容。如果你愿意,你可以通过在定义字段时调用 alwaysShow
方法来指定 Trix 字段应始终显示其内容
Trix::make('Biography')->alwaysShow(),
如果你希望允许用户将照片拖放到 Trix
字段中,则可以将 withFiles
方法链接到字段的定义上。在调用 withFiles
方法时,你应传递应存储照片的 文件系统磁盘 的名称
use Laravel\Nova\Fields\Trix;
Trix::make('Biography')->withFiles('public'),
此外,Nova 将定义两个数据库表来存储待处理和已持久化的 Field
上传。在安装期间运行 Nova 的迁移时,将自动创建这两个表:nova_pending_field_attachments
和 nova_field_attachments
。
最后,在您的 routes/console.php
文件中,您应该注册一个 每日计划任务,以从待处理附件表和存储中清除任何过时的附件。为了方便起见,Laravel Nova 提供了完成此任务所需的作业实现
use Illuminate\Support\Facades\Schedule;
use Laravel\Nova\Fields\Attachments\PruneStaleAttachments;
Schedule::call(new PruneStaleAttachments)->daily();
UiAvatar
字段不对应于应用程序数据库中的任何列。相反,此字段将生成一个包含用户缩写的简单头像。此字段由 ui-avatars.com 提供支持。
默认情况下,UiAvatar
图像将根据模型的 name
列的值生成。但是,如果你的用户名未存储在 name
列中,则可以将自定义列名传递给字段的 make
方法
use Laravel\Nova\Fields\UiAvatar;
// Using the "name" column...
UiAvatar::make(),
// Using a custom column...
UiAvatar::make('Avatar', 'full_name'),
如有必要,你可以调用 resolveUsing
方法来指定一个闭包,该闭包将被调用以确定用于生成头像的名称
UiAvatar::make()->resolveUsing(function () {
return implode(' ', explode('@', $this->email));
}),
可以使用 squared
方法显示具有方形边缘的图像缩略图。此外,可以使用 rounded
方法显示具有完全圆形边缘的图像
UiAvatar::make('Avatar', 'fullname')->squared(),
定义 UiAvatar
字段时可用的其他选项包括
选项 | 方法 | 说明 |
---|---|---|
字体大小 | fontSize(0.4) | 设置字体大小,范围为 0.1 至 1 。 |
粗体 | bold() | 将字体粗细设置为粗体。 |
背景颜色 | backgroundColor('1D4ED7') | 设置图像背景的十六进制颜色。 |
文本颜色 | color('FFFFFF') | 设置图像文本的十六进制颜色。 |
URL
字段将 URL 呈现为可点击链接,而不是纯文本
URL::make('GitHub URL'),
URL
字段还支持通过在定义字段时调用 displayUsing
方法来自定义生成的链接文本。displayUsing
方法接受一个闭包,该闭包应返回链接文本
URL::make('Receipt')
->displayUsing(fn () => "{optional($this->user)->name}'s receipt")
通过将闭包作为 URL
字段的第二个参数提供,你可以使用该字段为计算值呈现一个链接,该计算值不一定对应于关联模型数据库表中的列
URL::make('Receipt', fn () => $this->receipt_url)
Vapor 文件字段为使用 Laravel Vapor 将应用程序部署到无服务器环境时上传文件提供了便利性和兼容性
use Laravel\Nova\Fields\VaporFile;
VaporFile::make('Document'),
使用 VaporFile
字段上传文件时,Nova 将首先在 Amazon S3 上生成一个已签名的存储 URL。接下来,Nova 将直接将文件上传到 Amazon S3 存储桶中的临时存储。当资源被保存时,Nova 将文件移动到永久存储。
Vapor 存储
有关如何为 Vapor 应用程序处理文件存储的更多信息,请参阅 Laravel Vapor 存储文档。
Vapor 文件字段为使用 Laravel Vapor 将应用程序部署到无服务器环境时上传图像文件提供了便利性和兼容性
use Laravel\Nova\Fields\VaporImage;
VaporImage::make('Avatar'),
Vapor 图像文件支持 Image
字段可用的许多相同方法。
文件字段
要了解有关定义文件字段和处理上传的更多信息,请查看其他 文件字段文档。
为了验证 Vapor 文件的大小或其他属性,您需要通过 Storage
外观直接检查文件
use Illuminate\Support\Facades\Storage;
VaporFile::make('Document')
->rules('bail', 'required', function ($attribute, $value, $fail) use ($request) {
if (Storage::size($request->input('vaporFile')[$attribute]['key']) > 1000000) {
return $fail('The document size may not be greater than 1 MB');
}
}),
除了显示与数据库中的列直接关联的字段外,Nova 还允许您创建“计算字段”。计算字段可用于显示与数据库列无关的计算值。由于它们与数据库列无关,因此计算字段可能不可“排序”。可以通过将可调用对象(而不是列名)作为字段的 make
方法的第二个参数来创建这些字段
Text::make('Name', function () {
return $this->first_name.' '.$this->last_name;
}),
模型实例将传递给计算字段可调用对象,允许您在计算字段值时访问模型的属性
Text::make('Name', function ($model) {
return $model->first_name.' '.$model->last_name;
}),
模型属性访问
正如您在上面的示例中可能注意到的,您还可以使用 $this
访问资源的基础模型属性和关系。
默认情况下,Vue 将转义计算字段的内容。如果您需要在字段中呈现 HTML 内容,请在定义字段时调用 asHtml
方法
Text::make('Status', function () {
return view('partials.status', [
'isPassing' => $this->isPassing(),
])->render();
})->asHtml(),
有时您可能只想允许用户在资源上创建和更新某些字段。您可以通过在字段上调用 readonly
方法将字段标记为“只读”,这将禁用字段的相应输入。您可以将布尔参数传递给 readonly
方法以动态控制字段是否应为“只读”
Text::make('Email')->readonly(optional($this->resource)->trashed()),
您还可以将闭包传递给 readonly
方法,并且闭包的结果将用于确定字段是否应为“只读”。闭包将接收当前 NovaRequest
作为其第一个参数
Text::make('Email')->readonly(function ($request) {
return ! $request->user()->isAdmin();
}),
如果您只想在创建或附加资源时将字段标记为“只读”,则可以使用 NovaRequest
实例分别提供的 isCreateOrAttachRequest
和 isUpdateOrUpdateAttachedRequest
方法
Text::make('Email')->readonly(function ($request) {
return $request->isUpdateOrUpdateAttachedRequest();
}),
默认情况下,Nova 将使用红色星号来表示字段是必需的
Nova 通过查找字段验证规则内的 required
规则来确定是否应显示必需状态。例如,具有以下定义的字段将收到“必需”指示符
Text::make('Email')->rules('required'),
当您有复杂的 required
验证要求时,可以通过在定义字段时将布尔值传递给 required
方法来手动将字段标记为必需。这将通知 Nova 在 UI 中应显示“必需”指示符
Text::make('Email')->required(true),
此外,您还可以将闭包传递给 required
方法以确定是否应将字段标记为必需。闭包将收到 NovaRequest
的实例。闭包返回的值将用于确定字段是否必需
use Illuminate\Validation\Rule;
Text::make('Email')->required(function ($request) {
return $this->notify_via_email;
}),
required()
限制
required()
方法只会向 Nova UI 添加“必需”指示符。您仍必须定义在验证期间应应用的相关要求 rules()
。
默认情况下,Nova 尝试存储所有带有值的字段,但是,有时您可能希望 Nova 在字段为空时在相应的数据库列中存储 null
值。为此,您可以在字段定义中调用 nullable
方法
Text::make('Position')->nullable(),
您还可以使用 nullValues
方法设置应解释为 null
值的值,该方法接受数组或闭包作为其唯一参数
Text::make('Position')->nullable()->nullValues(['', '0', 'null']),
Text::make('Position')->nullable()->nullValues(function ($value) {
return $value == '' || $value == 'null' || (int)$value === 0;
}),
如果您想在字段下方放置“帮助”文本,则可以在定义字段时调用 help
方法
Text::make('Tax Rate')->help(
'The tax rate to be applied to the sale'
),
如有必要,您可以在字段的帮助文本中包含 HTML 以进一步自定义帮助文本
Text::make('First Name')->help(
'<a href="#">External Link</a>'
),
Text::make('Last Name')->help(
view('partials.help-text', ['name' => $this->name])->render()
),
默认情况下,Nova 在创建/更新表单上将字段显示在其标签旁边,但是某些字段(如“代码”、“Markdown”和“Trix”)可能会受益于通过将字段放在其相应标签下方而获得的额外宽度。可以使用 stacked
方法将字段堆叠在其标签下方
Trix::make('Content')->stacked(),
您可以使用 fullWidth
方法指示字段应为“全宽”
Trix::make('Content')->fullWidth(),
您可以使用 textAlign
方法更改字段的文本对齐方式
Text::make('Phone Number')->textAlign('left'),
以下对齐方式有效
左对齐
居中对齐
右对齐
resolveUsing
方法允许您自定义从数据库中检索字段后但在将其发送到 Nova 前端之前对其进行格式化的方式。此方法接受一个回调,该回调接收底层数据库列的原始值
Text::make('Name')->resolveUsing(function ($name) {
return strtoupper($name);
}),
如果您希望仅在字段显示在资源的“索引”或“详细信息”页面上时自定义其格式化方式,则可以使用 displayUsing
方法。与 resolveUsing
方法类似,此方法接受一个回调
Text::make('Name')->displayUsing(function ($name) {
return strtoupper($name);
}),
filterable
方法允许您为资源、关系和透镜上的给定字段启用方便的自动过滤功能。Nova 生成的过滤器将自动通过资源索引上的资源过滤器菜单提供
DateTime::make('Created At')->filterable(),
filterable
方法还接受一个闭包作为参数。此闭包将接收过滤器查询,然后您可以对其进行自定义以根据自己的喜好过滤资源结果
Text::make('Email')->filterable(function ($request, $query, $value, $attribute) {
$query->where($attribute, 'LIKE', "{$value}%");
}),
根据被标记为可过滤的底层字段类型,生成的过滤器将是文本过滤器、选择过滤器、数字范围过滤器或日期范围过滤器。
dependsOn
方法允许您指定字段的配置依赖于一个或多个其他字段的值。dependsOn
方法接受一个依赖字段属性的数组
和一个修改当前字段实例配置的闭包。
依赖字段允许高级自定义,例如根据另一个字段的状态切换只读模式、验证规则等
use Laravel\Nova\Fields\FormData;
use Laravel\Nova\Fields\Select;
use Laravel\Nova\Fields\Text;
use Laravel\Nova\Http\Requests\NovaRequest;
Select::make('Purchase Type', 'type')
->options([
'personal' => 'Personal',
'gift' => 'Gift',
]),
// Recipient field configuration is customized based on purchase type...
Text::make('Recipient')
->readonly()
->dependsOn(
['type'],
function (Text $field, NovaRequest $request, FormData $formData) {
if ($formData->type === 'gift') {
$field->readonly(false)->rules(['required', 'email']);
}
}
),
要为创建和更新资源分别定义依赖字段,可以使用 dependsOnCreating
和 dependsOnUpdating
方法。
以下字段类型可能依赖于其他字段
以下字段类型可能不会依赖于其他字段,因为它们不会向 Nova 实时报告其更改
dependsOn
切换字段可见性 依赖字段的一个常见用例是根据另一个字段的值切换字段可见性。你可以使用 hide
和 show
方法来实现此目的
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Boolean;
use Laravel\Nova\Fields\FormData;
use Laravel\Nova\Http\Requests\NovaRequest;
Boolean::make('Anonymous Comment', 'anonymous')
->default(true),
BelongsTo::make('User')
->hide()
->rules('sometimes')
->dependsOn('anonymous', function (BelongsTo $field, NovaRequest $request, FormData $formData) {
if ($formData->boolean('anonymous') === false) {
$field->show()->rules('required');
}
}),
dependsOn
设置字段值 依赖字段的另一个常见用例是根据另一个字段的值设置字段的值。你可以使用 setValue
方法来实现此目的
use Laravel\Nova\Fields\DateTime;
use Laravel\Nova\Fields\FormData;
use Laravel\Nova\Http\Requests\NovaRequest;
DateTime::make('Created At'),
DateTime::make('Updated At')->dependsOn(['created_at'], function (DateTime $field, NovaRequest $request, FormData $form) {
$field->setValue(Carbon::parse($form->created_at)->addDays(7));
}),
在与依赖字段交互时,你可以通过 resource
方法检索当前资源和相关资源 ID
use Laravel\Nova\Fields\BelongsTo;
use Laravel\Nova\Fields\Currency;
BelongsTo::make(__('Books'), 'books', Book::class),
Currency::make('Price')
->dependsOn('books', function ($field, NovaRequest $request, $formData) {
$bookId = (int) $formData->resource(Book::uriKey(), $formData->books);
if ($bookId == 1) {
$field->rules([
'required', 'numeric', 'min:10', 'max:199'
])->help('Price starts from $10-$199');
return;
}
$field->rules([
'required', 'numeric', 'min:0', 'max:99'
])->help('Price starts from $0-$99');
}),
字段是“可宏化的”,这允许你在运行时向 Field
类添加其他方法。Field
类的 macro
方法接受一个闭包,该闭包将在调用宏时执行。宏闭包可以通过 $this
访问字段的其他方法,就像它是字段类的真实方法一样。例如,以下代码向 Field
类添加了一个 toUpper
方法
use Illuminate\Support\Str;
use Laravel\Nova\Fields\Field;
Field::macro('toUpper', function () {
return $this->displayUsing(function ($value) {
return Str::upper($value);
});
});
一旦定义了宏,就可以在定义任何字段时使用它
Text::make('Name')->toUpper(),
如有必要,你可以定义接受其他参数的宏
use Laravel\Nova\Fields\Field;
Field::macro('showWhen', function ($condition) {
$condition === true ? $this->show() : $this->hide();
return $this;
});
你还可以仅向特定类型的 Field
添加宏。例如,你可以向 DateTime
字段类添加一个 withFriendlyDate
宏
use Laravel\Nova\Fields\DateTime;
DateTime::macro('withFriendlyDate', function () {
return $this->tap(function ($field) {
$field->displayUsing(function ($d) use ($field) {
if ($field->isValidNullValue($d)) {
return null;
}
return Carbon::parse($d)->diffForHumans();
});
});
});