构建你的第一个 Laravel Nova 工具
发布于 作者 Joe Dixon
最近,我利用了黑色星期五的促销活动,尽管我当时没有用,但我还是购买了 Laravel Nova 的许可证。我对它所看到的印象深刻,迫切想要尝试一下。
我决定把我的一个开源包 Laravel 翻译 移植到一个 Nova 工具中会很有趣。
相关:构建一个 Laravel 翻译包。
如果你不知道,工具是 Nova 允许开发者向开箱即用的功能中添加额外的自定义功能的一种方法。
本文将带你了解我在构建它时采取的步骤。
Nova 文档
不知道从哪里开始,我前往文档。正如你对 Laravel 产品的预期,文档非常棒。有一个部分专门介绍了 构建工具 以及自定义 Nova 的其他所有方法。
几分钟后,我就能理解我需要做什么了。
Nova 脚手架
Nova 自带一个 CLI 命令,它可以为你生成工具的脚手架,php artisan nova:tool
。在运行这个命令时,你需要传入工具在 Packagist 中的 vendor/name
格式的名称,它会在生成 composer.json
文件时使用它。这意味着它一旦开发完成就可以发布了。
工具的完整脚手架包括开始开发所需的一切,包括服务提供者、启动 JavaScript 和 SASS 文件,以及用于在应用程序中注册工具的类。

Nova 服务提供者
工具有自己的服务提供者,它可以被引导。这与 Laravel 服务提供者非常相似。它扩展了标准 Laravel 应用程序中使用的 Illuminate\Support\ServiceProvider
。这意味着所有方法(如加载路由、视图、迁移等)都可用。
与标准 Laravel 服务提供者不同,所有必要的视图和路由的连接都开箱即用。
// Views$this->loadViewsFrom(__DIR__.'/../resources/views', 'nova-translation'); // RoutesRoute::middleware(['nova', Authorize::class]) ->prefix('nova-vendor/nova-translation') ->group(__DIR__.'/../routes/api.php');
如你所见,一些 Laravel Nova 中间件会自动应用于路由。nova
中间件组会应用在 nova.php
配置文件中定义的任何中间件,Authorize::class
会应用在工具类中设置的任何自定义授权。稍后会详细介绍。
路由也在你的供应商前缀下注册,所以它们不会与任何其他路由冲突。
最后,你的路由从自动生成的 routes/api.php
文件中加载,该文件是使用工具自动生成的。
Nova 工具类
如前所述,工具类会自动为你创建。它使用运行 php artisan nova:tool vendor/name
时提供的名称的驼峰式版本命名。
你不需要在这里做任何事情,但可以修改渲染导航或加载哪些资产的方式。
对于我的包,我不需要对这个文件进行任何更改。
Nova 导航
Nova 使得在应用程序主侧边栏中添加指向你的工具的链接变得非常容易。同样,这是通过提供一个包含默认导航链接的 navigation.blade.php
文件并从工具类中加载它来自动生成的。
public function renderNavigation(){ return view('nova-translation::navigation');}
你可以随意编辑这个文件以满足你的需求。通常情况下,这将涉及更新在导航中渲染的 SVG 图标。方便的是,Nova 自带了一套 图标,你可以随意使用。
Laravel Nova 前端
Nova 前端是一个 Vue.js 应用程序。新的工具会初始化一个 tool.js
文件,你可以在其中使用 Vue 的路由器来定义任何需要的路由。从那里,你可以随意构建应用程序,就像你想要的那样。正如你所预期的那样,你的应用程序索引的路由是为你定义的,但你可以随意更新它,如果需要的话。
Nova.booting((Vue, router) => { router.addRoutes([ { name: 'nova-translation', path: '/nova-translation', component: require('./views/LanguagesIndex'), }, ... ])})
工具使用 Laravel Mix 编译,一个配置文件包含在脚手架中。这允许你运行开发和生产构建,甚至在文件更改时触发重新构建,使用你可能熟悉的命令,如 npm run watch
。
在开发前端时,我喜欢的一件事是能够利用 Nova 核心中的所有 Vue 组件。
能够引入像加载视图这样的东西,它会自动处理你的组件的加载状态,或者下拉菜单组件,用于构建用户界面,这是非常有用的。
<template> <loading-view :loading="initialLoading"> // ships with Nova <loading-card :loading="loading" class="card"> // ships with Nova // show something custom in here when loading state changes </loading-card> </loading-view></template> <script>export default { data() { return { initialLoading: true, loading: false, languages: {} } }, methods: { listLanguages() { Nova.request().get('/nova-vendor/nova-translation/languages') .then((response) => { this.languages = response.data; this.initialLoading = false; this.loading = false; }) } }, created() { this.listLanguages() },}</script>
如你所见,我使用了 Nova 附带的 LoadingView
和 LoadingCard
组件。然后,我将我的组件的加载状态作为道具传递,加载状态转换会自动处理。结果是在我的数据准备好的同时,加载动画会被渲染出来。

注册 Nova 工具
构建好工具后,最后一步是让 Nova 知道它的存在,方法是将其注册到应用程序中。这是通过将工具类添加到 NovaServiceProvider
的 registerTools
方法中来实现的。
protected function registerTools(){ Nova::tools([ new Dashboard, new ResourceManager, new NovaTranslation, ]);}
Laravel 社区
撇开技术实现不谈,我想强调在开发这个工具过程中发生的一件事。
在构建过程中,我想实现页面顶部在进行 ajax 驱动的搜索时出现的蓝色加载条。如果你之前使用过 Nova,它与你搜索任何资源时出现的加载器相同。
我当时很累,熬夜想完成它,却怎么也想不通。我决定联系 David 在 Twitter 上寻求一些建议。十分钟后,我收到了一条回复,正是需要知道的内容。
当你搜索时,查询字符串会被更新,导航到新 URL 时,那个加载条就会出现。
— HEMPHILL (@davidhemphill) 2018 年 11 月 29 日
非常感谢 David 帮助我解决了这个问题,也感谢更广泛的 Laravel 社区。这肯定不是我最后一次在需要的时候得到社区成员的帮助。
结论
Nova 的开发体验非常棒。从不知道从哪里开始到将我的包移植过来,只花了几个晚上,这证明了,不仅是文档,而且是 Nova 本身的规划和执行。正如 Laravel 生态系统中的所有事物一样,它是在极度谨慎和注重细节的情况下构建的,使开发人员的入职体验既快捷又轻松。我个人来说,迫不及待地想开始下一个项目!
如果你想看看我构建的工具,请在 Nova Packages 上查看它,像往常一样,如果你有任何问题,可以在 Twitter 上找到我。