有时,你的企业可能需要 Nova 未提供的额外功能。因此,Nova 允许你创建自定义工具并将其添加到 Nova 侧边栏。Nova 工具的可定制性令人难以置信,因为它们主要由一个完全由你控制的单文件 Vue 组件组成。在你的 Vue 组件中,你可以自由地向应用程序中的任何控制器发出 HTTP 请求。
可使用 nova:tool Artisan 命令生成自定义工具。默认情况下,所有新工具都将放在应用程序的 nova-components 目录中。使用 nova:tool 命令生成工具时,传递给该命令的工具名称应遵循 Composer vendor/package 格式。因此,如果我们要构建一个价格跟踪器工具,可以运行以下命令来生成工具:
php artisan nova:tool acme/price-tracker生成工具时,Nova 会提示你安装工具的 NPM 依赖项、编译其资产并更新应用程序的 composer.json 文件。所有自定义工具都会作为 Composer 「路径」存储库 与应用程序一起注册。
Nova 工具包含构建工具所需的所有脚手架。每个工具甚至都包含自己的 composer.json 文件,可随时在 GitHub 或你选择的源控制提供商上与全世界共享。
Nova 工具可在应用程序的 App/Providers/NovaServiceProvider 类中注册。你的服务提供商包含一个 tools 方法,该方法会返回一个工具数组。要注册工具,只需将其添加到该方法返回的工具列表中即可。例如,如果你创建了一个名为 acme/price-tracker 的 Nova 工具,您可以这样注册该工具:
use Acme\PriceTracker\PriceTracker;
/**
* 获取应在 Nova 侧边栏中列出的工具。
*
* @return array
*/
public function tools()
{
return [
new PriceTracker,
];
}如果你只想向特定用户公开某个工具,你可以在工具注册时链上 canSee 方法。 canSee 方法接受一个闭包,该闭包将返回 true 或 false。闭包将接收传入的 HTTP 请求:
use Acme\PriceTracker\PriceTracker;
/**
* 获取应在 Nova 侧边栏中列出的工具。
*
* @return array
*/
public function tools()
{
return [
(new PriceTracker)->canSee(function ($request) {
return false;
}),
];
}Nova 生成的每个工具都有自己的服务提供商和「工具」类。以 price-tracker 工具为例,工具类将位于 src/PriceTracker.php。如前所述,工具类必须在应用程序的 NovaServiceProvider 中注册。
工具的服务提供者也位于工具的 src 目录中,并在工具的 composer.json 文件的 extra 部分注册,以便 Laravel 自动加载。
通常,你需要定义工具调用的 Laravel 路由。Nova 生成工具时,会创建 routes/inertia.php 和 routes/api.php 路由文件。
routes/inertia.php 文件的任务是通过 Inertia 渲染工具,而 routes/api.php 文件可用于定义任何路由,以便你的基于 Inertia 的工具向其发出请求,从而收集更多数据或执行更多任务。
你的工具的 ToolServiceProvider 会自动在路由组中定义 routes/api.php 文件中的所有路由。路由组指定所有「API 路由」(通常通过 Nova.request从客户端调用)都应接收 /nova-vendor/tool-name URL 前缀,其中 tool-name 是你工具的「kebab-case」名称。
同样,routes/inertia.php 文件中的路由也会被置于路由组中,该组会在文件中的所有路由前加上工具名称。
你可以自由修改路由组定义,但应确保你的 Nova 工具能与其他 Nova 软件包轻松共存。
Nova 工具在生成时带有一个 Authorize 中间件。你通常不需要修改此中间件,因为它会在处理对工具路由组内路由的任何请求之前,自动确定已通过身份验证的用户是否可以 canSee 工具;不过,如果需要,你可以自由修改此中间件。
你的 Nova 工具类包含一个 menu 方法。该方法应返回一个 自定义菜单,用于渲染工具左侧的导航链接。你可以根据需要自定义此方法:
use Illuminate\Http\Request;
use Laravel\Nova\Menu\MenuSection;
/**
* 创建菜单,渲染工具的导航链接。
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function menu(Request $request)
{
return MenuSection::make('Price Tracker')
->path('/price-tracker')
->icon('server');
}自定义主菜单
如果你已 自定义 Nova 的侧边栏菜单,你的工具链接将不会自动显示在 Nova 的侧边栏中。你需要在自定义的 Nova::mainMenu 回调中手动定义工具的菜单。
Nova 使用由 Steve Schoger 制作的免费 Heroicons 图标集。因此,在向 icon 方法提供图标名称时,只需指定其中一个图标的名称即可。
Nova 生成工具时,会为你生成 resources/js 和 resources/css 目录。这些目录包含工具的 JavaScript 和 CSS。这些目录中值得关注的主要文件有 resources/js/components/Tool.vue 和 resources/css/tool.css。
Tool.vue 文件是一个包含工具前端的单文件 Vue 组件。通过该文件,你可以随意构建你的工具。你的工具可通过 Nova.request 使用 Axios 发送 HTTP 请求。
Nova 工具类包含一个 boot 方法。该方法在工具注册并可用时执行。默认情况下,该方法会注册工具的编译资产,以便 Nova 前端可以使用它们:
use Laravel\Nova\Nova;
use Laravel\Nova\Events\ServingNova;
/**
* 执行工具注册所需的任何任务。
*
* @return void
*/
public function boot()
{
Nova::script('price-tracker', __DIR__.'/../dist/js/tool.js');
Nova::style('price-tracker', __DIR__.'/../dist/css/tool.css');
}你的组件已引导,Inertia.js 组件已在 resources/js/tool.js 文件中注册。你可以根据需要修改该文件或在此注册其他组件:
Nova.booting((Vue, store) => {
Vue.component("PriceTrackerHeader", require("./components/Header").default);
});Nova 工具包含一个 webpack.mix.js 文件,该文件在 Nova 创建工具时生成。你可以使用 NPM dev 和 prod 命令构建你的工具:
# 为本地开发编译资源...
npm run dev
# 编译并最小化资源...
npm run prod此外,你还可以运行 NPM watch 命令,在资产发生变化时自动编译它们:
npm run watch工具中包含的 Vue 页面组件可访问 Nova 注册的所有组件和插件,包括 v-tooltip。例如,你工具的 resources/js/pages/Tool.vue 桩件模版将包含由 Inertia.js Head 组件管理的默认页面标题:
<template>
<Head title="PriceTracker" />
</template>