有时,您的业务可能需要 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 "path" 存储库 注册到您的应用程序。
Nova 工具包含构建工具所需的所有脚手架。每个工具甚至包含自己的 composer.json
文件,并已准备好与 GitHub 或您选择的源代码控制提供商共享。
可以在应用程序的 App/Providers/NovaServiceProvider
类中注册 Nova 工具。您的服务提供者包含一个 tools
方法,该方法返回一个工具数组。要注册您的工具,只需将其添加到此方法返回的工具列表中。例如,如果您创建了一个名为 acme/price-tracker
的 Nova 工具,您可以像这样注册该工具
use Acme\PriceTracker\PriceTracker;
/**
* Get the tools that should be listed in the Nova sidebar.
*
* @return array
*/
public function tools()
{
return [
new PriceTracker,
];
}
如果您只想向特定用户公开某个工具,可以在工具注册时将 canSee
方法链接到一起。canSee
方法接受一个闭包,该闭包应该返回 true
或 false
。闭包将接收传入的 HTTP 请求
use Acme\PriceTracker\PriceTracker;
/**
* Get the tools that should be listed in the Nova sidebar.
*
* @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 的工具将向其发出请求以收集更多数据或执行其他任务的任何路由。
routes/api.php
文件中的所有路由都由工具的 ToolServiceProvider
在路由组中自动定义。路由组指定所有“API 路由”(通常通过 Nova.request 从客户端调用)应接收 /nova-vendor/tool-name
URL 前缀,其中 tool-name
是工具的“kebab-case”名称。
类似地,routes/inertia.php
文件中的路由也放置在路由组中,该路由组将文件中的所有路由都加上工具名称的前缀。
您可以随意修改此路由组定义,但应确保您的 Nova 工具能够轻松地与其他 Nova 包共存。
您的 Nova 工具是使用 Authorize
中间件生成的。您通常不需要修改此中间件,因为它会在处理工具路由组中的任何请求之前自动确定经过身份验证的用户是否可以“查看”该工具;但是,如果需要,您可以随意修改此中间件。
您的 Nova 工具类包含一个 menu
方法。此方法应返回一个 自定义菜单,该菜单呈现工具的左侧导航链接。您可以根据需要自定义此方法。
use Illuminate\Http\Request;
use Laravel\Nova\Menu\MenuSection;
/**
* Build the menu that renders the navigation links for the tool.
*
* @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;
/**
* Perform any tasks that need to happen on tool registration.
*
* @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
命令构建您的工具。
# Compile your assets for local development...
npm run dev
# Compile and minify your assets...
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>