Laravel Nova 是一个适用于 Laravel 应用程序的漂亮管理仪表盘。当然,Nova 的主要功能是使用 Eloquent 管理底层数据库记录。Nova 通过允许您定义与应用程序中每个 Eloquent 模型相对应的 Nova “资源”来实现此目的。
默认情况下,Nova 资源存储在应用程序的 app/Nova
目录中。您可以使用 nova:resource
Artisan 命令生成新资源
php artisan nova:resource Post
资源最基本和最根本的属性是其 model
属性。此属性告诉 Nova 该资源对应哪个 Eloquent 模型
/**
* The model the resource corresponds to.
*
* @var string
*/
public static $model = 'App\Models\Post';
新创建的 Nova 资源仅包含一个 ID
字段定义。别担心,我们很快就会为我们的资源添加更多字段。
保留的资源名称
Nova 包含一些保留字,不能用于资源名称
自动注册
默认情况下,app/Nova
目录中的所有资源都将自动注册到 Nova。您无需手动注册它们。
在资源在 Nova 仪表盘中可用之前,它们必须首先在 Nova 中注册。资源通常在应用程序的 app/Providers/NovaServiceProvider.php
文件中注册。此文件包含与 Nova 安装相关的各种配置和引导代码。
如上所述,您无需手动注册资源;但是,如果您选择这样做,可以通过覆盖 NovaServiceProvider
的 resources
方法来实现.
手动注册资源有两种方法。您可以使用 resourcesIn
方法指示 Nova 注册给定目录中的所有 Nova 资源。或者,您可以使用 resources
方法手动注册各个资源
use App\Nova\User;
use App\Nova\Post;
/**
* Register the application's Nova resources.
*
* @return void
*/
protected function resources()
{
Nova::resourcesIn(app_path('Nova'));
Nova::resources([
User::class,
Post::class,
]);
}
一旦您的资源在 Nova 中注册,它们将出现在 Nova 侧边栏中
如果您不希望资源出现在侧边栏中,您可以覆盖资源类的 displayInNavigation
属性
/**
* Indicates if the resource should be displayed in the sidebar.
*
* @var bool
*/
public static $displayInNavigation = false;
您可以通过在资源类中定义 menu
方法来自定义资源的菜单
use Illuminate\Http\Request;
/**
* Get the menu that should represent the resource.
*
* @param \Illuminate\Http\Request $request
* @return \Laravel\Nova\Menu\MenuItem
*/
public function menu(Request $request)
{
return parent::menu($request)->withBadge(function () {
return static::$model::count();
});
}
有关更多信息,请参阅 菜单自定义 文档。
如果您想将资源分成不同的侧边栏组,您可以覆盖资源类的 group
属性
/**
* The logical group associated with the resource.
*
* @var string
*/
public static $group = 'Admin';
Nova 支持对你的资源进行一些可视化自定义选项。
有时在你的资源索引表中显示更多数据会很方便。为了实现这一点,你可以使用“紧凑”表格样式选项,它旨在增加表格行的可视化密度。要实现这一点,请覆盖你资源类中的静态 $tableStyle
属性或静态 tableStyle
方法
/**
* The visual style used for the table. Available options are 'tight' and 'default'.
*
* @var string
*/
public static $tableStyle = 'tight';
这将以更少的可视化高度显示你的表格行,从而能够显示更多数据
你可以指示 Nova 显示列边框,方法是覆盖你资源类中的静态 $showColumnBorders
属性或静态 showColumnBorders
方法
/**
* Whether to show borders for each column on the X-axis.
*
* @var bool
*/
public static $showColumnBorders = true;
将此属性设置为 true
将指示 Nova 在每个表格项上显示带边框的表格
默认情况下,当点击资源表行时,Nova 将导航到该资源的详细信息视图。但是,你可能希望 Nova 转而导航到编辑表单。你可以通过更改资源类上的 clickAction
属性来自定义此行为
/**
* The click action to use when clicking on the resource in the table.
*
* Can be one of: 'detail' (default), 'edit', 'select', 'preview', or 'ignore'.
*
* @var string
*/
public static $clickAction = 'edit';
选择 select
选项将选中资源行的复选框。ignore
选项指示 Nova 完全忽略点击事件。
如果你需要在你的字段、资源标题或资源副标题中例行访问资源的关系,那么将该关系添加到你的资源的 with
属性中可能是一个好主意。此属性指示 Nova 在检索资源时始终急切加载列出的关系。
例如,如果你在 Post
资源的 subtitle
方法中访问了 Post
资源的 user
关系,则应将 user
关系添加到 Post
资源的 with
属性中
/**
* The relationships that should be eager loaded on index queries.
*
* @var array
*/
public static $with = ['user'];
有时,您可能希望在使用现有资源中的所有数据作为起点时创建一个新资源。Nova 的资源复制功能就是这样做的。在单击复制按钮后,您将被带到一个资源创建表单,其中所有复制资源的数据都已注入到表单中并准备进行调整
要自定义复制模型,您可以在资源类上覆盖 replicate
方法
/**
* Return a replicated resource.
*
* @return static
*
* @throws \InvalidArgumentException
*/
public function replicate()
{
return tap(parent::replicate(), function ($resource) {
$model = $resource->model();
$model->name = 'Duplicate of '.$model->name;
});
}
附件可能无法复制
使用 withFiles
方法的 Markdown
和 Trix
字段可能无法复制。
如果您需要存储对原始资源 ID 的引用,则可以访问复制请求中的 fromResourceId
值。通常,此值将从侦听模型的 creating
事件的事件侦听器或观察器中访问
namespace App\Observers;
use App\Models\Post;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Nova;
class PostObserver
{
/**
* Handle the creation of a new Post.
*
* @param \App\Models\Post $model
* @return void
*/
public function creating(Post $model): void
{
Nova::whenServing(function (NovaRequest $request) use ($model) {
$model->parent_id = $request->input('fromResourceId');
});
}
}
所有 Nova 操作都使用您熟悉的典型 save
、delete
、forceDelete
、restore
Eloquent 方法。因此,很容易侦听 Nova 触发的模型事件并对它们做出反应。最简单的方法是简单地将 Laravel 模型观察器附加到模型
namespace App\Providers;
use App\Models\User;
use App\Observers\UserObserver;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();
User::observe(UserObserver::class);
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
//
}
}
如果您想附加一个仅在 Nova 相关的 HTTP 请求期间调用其方法的观察器,则可以使用 Laravel\Nova\Observable
类提供的 make
方法注册观察器。通常,这应该在应用程序的 NovaServiceProvider
中完成
use App\Models\User;
use Laravel\Nova\Observable;
use App\Observers\UserObserver;
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
parent::boot();
Observable::make(User::class, UserObserver::class);
}
或者,您可以在 Observer
本身中使用 Nova 的 whenServing
方法确定当前 HTTP 请求是否正在提供与 Nova 相关的请求
namespace App\Observers;
use App\Models\User;
use Illuminate\Http\Request;
use Laravel\Nova\Http\Requests\NovaRequest;
use Laravel\Nova\Nova;
class UserObserver
{
/**
* Handle the User "created" event.
*
* @param \App\Models\User $user
* @return void
*/
public function created(User $user)
{
Nova::whenServing(function (NovaRequest $request) use ($user) {
// Only invoked during Nova requests...
}, function (Request $request) use ($user) {
// Invoked for non-Nova requests...
});
// Always invoked...
}
}
Nova 还允许您在资源上定义以下静态方法,作为仅在从 Laravel Nova 中执行相应资源操作时调用的挂钩
afterCreate
afterUpdate
afterDelete
afterForceDelete
afterRestore
例如,您可能希望在 Nova 中创建用户后发送电子邮件验证通知
use App\Models\User;
use App\Nova\Resource;
use Illuminate\Database\Eloquent\Model;
use Laravel\Nova\Http\Requests\NovaRequest;
class User extends Resource
{
/**
* Register a callback to be called after the resource is created.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public static function afterCreate(NovaRequest $request, Model $model)
{
$model->sendEmailVerificationNotification();
}
}
如果某个模型在 Nova 上次检索后已更新,Nova 将自动响应一个 409 冲突
HTTP 状态代码并显示错误消息,以防止意外的模型更改。如果在您在资源上打开“编辑”页面后,另一位用户更新了该模型,则可能会发生这种情况。此功能也称为 Nova “交通警察”。
如果您不关心防止冲突,可以通过在给定的资源类上将 trafficCop
属性设置为 false
来禁用交通警察功能
/**
* Indicates whether Nova should check for modifications between viewing and updating a resource.
*
* @var bool
*/
public static $trafficCop = false;
如果您有更严格的自定义需求,还可以覆盖资源上的 trafficCop
方法,以确定是否应启用此功能
/**
* Indicates whether Nova should check for modifications between viewing and updating a resource.
*
* @param \Illuminate\Http\Request $request
* @return bool
*/
public static function trafficCop(Request $request)
{
return static::$trafficCop;
}
时间同步
如果您在使用交通警察时遇到问题,您应该确保您的系统时间使用 NTP 正确同步。
Nova 可以自动在指定的时间间隔内获取资源的最新记录。要启用轮询,请覆盖资源类的 polling
属性
/**
* Indicates whether the resource should automatically poll for new resources.
*
* @var bool
*/
public static $polling = true;
要自定义轮询间隔,您可以在资源类上覆盖 pollingInterval
属性,其中包含 Nova 在获取新资源记录之前应等待的秒数
/**
* The interval at which Nova should poll for new resources.
*
* @var int
*/
public static $pollingInterval = 5;
默认情况下,当启用资源轮询时,一旦页面加载,就无法禁用它。您可以通过在资源类上将 showPollingToggle
属性设置为 true
来指示 Nova 为资源轮询显示一个开始/停止切换按钮
/**
* Indicates whether to show the polling toggle button inside Nova.
*
* @var bool
*/
public static $showPollingToggle = true;
然后,Nova 将显示一个可单击按钮,您可以使用该按钮为资源启用/禁用轮询
Nova 允许您轻松自定义在执行资源操作(例如创建或更新资源)后将用户重定向到何处
在幕后,Nova 的重定向功能使用 Inertia.js 的 visit
方法。因此,重定向仅限于 Laravel Nova 中的路径。您可以调用 URL::remote
方法重定向到外部 URL
use Laravel\Nova\URL;
return URL::remote('https://nova.laravel.net.cn');
你可以通过覆盖资源的 redirectAfterCreate
方法来定制用户在创建资源后被重定向到的位置
/**
* Return the location to redirect the user after creation.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Laravel\Nova\Resource $resource
* @return \Laravel\Nova\URL|string
*/
public static function redirectAfterCreate(NovaRequest $request, $resource)
{
return '/resources/'.static::uriKey().'/'.$resource->getKey();
}
你可以通过覆盖资源的 redirectAfterUpdate
方法来定制用户在更新资源后被重定向到的位置
/**
* Return the location to redirect the user after update.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @param \Laravel\Nova\Resource $resource
* @return \Laravel\Nova\URL|string
*/
public static function redirectAfterUpdate(NovaRequest $request, $resource)
{
return '/resources/'.static::uriKey().'/'.$resource->getKey();
}
你可以通过覆盖资源的 redirectAfterDelete
方法来定制用户在删除资源后被重定向到的位置
/**
* Return the location to redirect the user after deletion.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return \Laravel\Nova\URL|string|null
*/
public static function redirectAfterDelete(NovaRequest $request)
{
return null;
}
Nova 能够为你的资源列表显示分页链接。你可以根据应用程序的需求在三种不同的样式之间进行选择:“simple”、“load-more”和“links”
默认情况下,Nova 资源使用“simple”样式显示。但是,你可以通过更改应用程序的 config/nova.php
配置文件中的 pagination
配置选项的值,将其自定义为使用 load-more
或 links
样式
'pagination' => 'links',
如果你想自定义每个资源的“每页”过滤器菜单中显示的可选择最大结果数,可以通过自定义资源的 perPageOptions
属性来实现
/**
* The pagination per-page options configured for this resource.
*
* @return array
*/
public static $perPageOptions = [50, 100, 150];
或者,你可以在安装 Nova 时创建的应用程序的基本 Resource
类中覆盖 perPageOptions
方法
/**
* The pagination per-page options configured for this resource.
*
* @return array
*/
public static function perPageOptions()
{
return [50, 100, 150];
}
自定义 perPageOptions
和资源获取
在你的 Resource
中更改 perPageOptions
的值将导致 Nova 获取等于 perPageOptions
数组中第一个值的数量的资源。
使用 $perPageViaRelationship
属性,你还可以自定义当某个特定资源在另一个资源的详细信息视图中作为关系显示时显示的资源数
/**
* The number of resources to show per page via relationships.
*
* @var int
*/
public static $perPageViaRelationship = 10;
有时你可能需要将一组资源记录导出为 CSV 文件,以便你可以在电子表格应用程序中与数据交互或将数据导入另一个系统。值得庆幸的是,Nova 包含了导出资源数据的内置支持。
要开始,将 Laravel\Nova\Actions\ExportAsCsv
操作 添加到您的 Nova 资源中
use Laravel\Nova\Actions\ExportAsCsv;
use Laravel\Nova\Http\Requests\NovaRequest;
/**
* Get the actions available for the resource.
*
* @param \Laravel\Nova\Http\Requests\NovaRequest $request
* @return array
*/
public function actions(NovaRequest $request)
{
return [
ExportAsCsv::make(),
];
}
如果您希望允许用户对下载的 CSV 文件命名,您可以在注册操作时调用 nameable
方法
return [
ExportAsCsv::make()->nameable(),
];
如果您希望自定义和设置在生成的 CSV 中包含的字段的格式,您可以在注册操作时调用 withFormat
方法
return [
ExportAsCsv::make()->withFormat(function ($model) {
return [
'ID' => $model->getKey(),
'Name' => $model->name,
'Email Address' => $model->email,
];
}),
];
您可能希望自定义单个资源的索引列表的搜索去抖时间。例如,执行以检索某些资源的查询可能比其他查询花费更长的时间。您可以通过设置资源类上的 debounce
属性来自定义单个资源的搜索去抖
/**
* The debounce amount (in seconds) to use when searching this resource.
*
* @var float
*/
public static $debounce = 0.5; // 0.5 seconds
您可以在资源索引上按 C
键导航到“创建资源”页面。在资源详情页面上,E
键可用于导航到“更新资源”页面。