logo

菜单

概述

默认情况下,Nova 的左侧主导航菜单会显示应用程序的所有仪表盘、资源以及您注册的任何自定义工具。

Default Menu

在渲染主菜单时,Nova 会根据应用程序的 App\Providers\NovaServiceProvider 类中 dashboards 方法返回的顺序对仪表盘进行排序。

Nova 还会根据 Resource 类中定义的 group 属性,将您的资源自动分组到默认的“资源”菜单部分。此外,您注册的任何自定义工具都将按您在应用程序的 NovaServiceProvider 中定义的顺序列出。

自定义主菜单

虽然 Nova 的默认主菜单足以满足大多数应用程序的需求,但有时您可能希望根据自己的偏好完全自定义菜单。为此,Nova 允许您通过 Nova::mainMenu 方法定义自己的主菜单。通常,此方法应在应用程序的 App\Providers\NovaServiceProvider 类的 boot 方法中调用。

php
<?php

namespace App\Providers;

use App\Nova\License;
use App\Nova\Release;
use App\Nova\Series;
use App\Nova\User;
use Illuminate\Http\Request;
use Laravel\Nova\Dashboards\Main;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Nova;
use Laravel\Nova\NovaApplicationServiceProvider;

class NovaServiceProvider extends NovaApplicationServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        parent::boot();

        Nova::mainMenu(function (Request $request) {
            return [
                MenuSection::dashboard(Main::class)->icon('chart-bar'),

                MenuSection::make('Customers', [
                    MenuItem::resource(User::class),
                    MenuItem::resource(License::class),
                ])->icon('user')->collapsable(),

                MenuSection::make('Content', [
                    MenuItem::resource(Series::class),
                    MenuItem::resource(Release::class),
                ])->icon('document-text')->collapsable(),
            ];
        });
    }
}

Custom Menu

自定义用户菜单

Nova 还允许您自定义位于右上角导航区域的“用户”菜单。您可以通过调用 Nova::userMenu 方法来自定义 Nova 的用户菜单。此方法通常在应用程序的 App\Providers\NovaServiceProviderboot 方法中调用。

php
<?php

namespace App\Providers;

use Illuminate\Http\Request;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Nova;
use Laravel\Nova\NovaApplicationServiceProvider;

class NovaServiceProvider extends NovaApplicationServiceProvider
{
    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Nova::userMenu(function (Request $request, Menu $menu) {
            if ($request->user()->subscribed()) {
                $menu->append(
                    MenuItem::make('Subscriber Dashboard')
                        ->path('/subscribers/dashboard')
                );
            }

            $menu->prepend(
                MenuItem::make(
                    'My Profile',
                    "/resources/users/{$request->user()->getKey()}"
                )
            );

            return $menu;
        });
    }
}

用户菜单注销链接

默认情况下,Nova 配置为在用户菜单中显示“注销”链接。此链接不可删除。

用户菜单项

Nova 的用户菜单仅支持 MenuItem 对象。在用户菜单中使用 MenuSectionMenuGroup 将会抛出 Exception

追加/前置菜单

您可以调用Menu实例上的appendprepend方法,在菜单中添加或插入新项。这些方法通常在自定义用户菜单时最有用,因为您通常不希望完全替换现有菜单。

php
Nova::userMenu(function (Request $request, Menu $menu) {
    return $menu
        ->append(MenuItem::externalLink('API Docs', 'http://example.com'))
        ->prepend(MenuItem::link('My Profile', '/resources/users/'.$request->user()->getKey()));
    });

菜单部分代表顶级导航项,通常会显示一个相应的图标,代表菜单中项目的类型。您可以通过调用MenuSection::make方法创建一个新的菜单部分。此方法接受菜单部分的名称和应放置在部分内的菜单组/项目的数组。

php
use App\Nova\Dashboards\Sales;
use App\Nova\Lenses\MostValuableUsers;
use App\Nova\License;
use App\Nova\Refund;
use App\Nova\User;
use Illuminate\Http\Request;
use Laravel\Nova\Menu\Menu;
use Laravel\Nova\Menu\MenuGroup;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Nova;

Nova::mainMenu(function (Request $request, Menu $menu) {
    return [
        MenuSection::make('Business', [
            MenuGroup::make('Licensing', [
                MenuItem::dashboard(Sales::class),
                MenuItem::resource(License::class),
                MenuItem::resource(Refund::class),
                MenuItem::externalLink('Stripe Payments', 'https://dashboard.stripe.com/payments?status%5B%5D=successful'),
            ]),

            MenuGroup::make('Customers', [
                MenuItem::lens(User::class, MostValuableUsers::class),
            ]),
        ]),
    ];
});

除了显示链接列表,您还可以指示菜单部分只是一个指向其他位置的大型强调链接。为此,您可以在定义菜单部分时调用path方法。

php
use Laravel\Nova\Menu\MenuSection;

MenuSection::make('Dashboard')->path('/dashboards/main')

为了方便起见,如果您只是创建一个菜单部分作为指向 Nova 仪表盘的大型强调链接,您可以调用MenuSection::dashboard方法。

php
use App\Nova\Dashboards\Sales;
use Laravel\Nova\Menu\MenuSection;

MenuSection::dashboard(Sales::class),

由于您经常会创建指向 Nova 资源的链接,您可以使用resource方法快速创建指向给定资源的适当路径的链接。

php
use App\Nova\User;
use Laravel\Nova\Menu\MenuSection;

MenuSection::resource(User::class)

同样,您可以通过lens方法创建指向 Nova 透镜的链接。

php
use App\Nova\Lenses\MostValuableUsers;
use App\Nova\User;
use Laravel\Nova\Menu\MenuSection;

MenuSection::lens(User::class, MostValuableUsers::class)

菜单部分作为链接

定义为collapsable的菜单部分不支持也作为链接。在菜单部分为collapseable时调用path将导致不显示任何链接。

您可以在定义菜单部分时调用icon方法,自定义为菜单部分显示的图标。

php
use Laravel\Nova\Menu\MenuSection;

MenuSection::make('Resources', [
    // items
])->icon('briefcase')

Nova 使用由Steve Schoger提供的免费Heroicons图标集。因此,您只需在向icon方法提供图标名称时指定其中一个图标的名称。

您可以通过在MenuSection上调用withBadge方法并指定徽章的选项,为菜单部分添加视觉徽章。

php
use App\Models\Issue;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Badge;

// Passing a string directly
MenuSection::make('New Issues')
    ->path('/resources/issues/lens/new-issues')
    ->withBadge('New!', 'success')
    ->icon('document-text')

// Passing a Laravel\Nova\Badge instance directly
MenuSection::make('New Issues')
    ->path('/resources/issues/lens/new-issues')
    ->withBadge(Badge::make('New!', 'info'))
    ->icon('document-text')

// Using a closure to resolve the value
MenuSection::make('New Issues')
    ->path('/resources/issues/lens/new-issues')
    ->withBadge(fn () => Issue::count(), 'warning')
    ->icon('document-text')

条件徽章

使用 withBadgeIf 方法,您可以有条件地添加徽章,仅当满足给定条件时才添加。

php
use App\Models\Issue;
use Laravel\Nova\Menu\MenuSection;
use Laravel\Nova\Badge;

// Passing a string directly...
MenuSection::make('New Issues')
    ->path('/resources/issues/lens/new-issues')
    ->withBadgeIf('New!', 'info', fn () => Issue::count() > 0)

// Passing a Laravel\Nova\Badge instance...
MenuSection::make('New Issues')
    ->path('/resources/issues/lens/new-issues')
    ->withBadgeIf(Badge::make('New!', 'info'), fn () => Issue::count() > 0)

// Using a closure to resolve the value...
MenuSection::make('New Issues')
    ->path('/resources/issues/lens/new-issues')
    ->withBadgeIf(fn() => 'New!', 'info', fn () => Issue::count() > 0)

可折叠菜单部分

您可以在定义菜单部分时调用 collapsable 方法,使您的菜单部分可折叠。为了方便起见,Nova 会在请求之间记住该部分的打开状态。

php
use Laravel\Nova\Menu\MenuSection;

MenuSection::make('Resources', [
    //
])->collapsable()

有时您可能需要在菜单部分和菜单项之间添加另一个逻辑级别。在这种情况下,菜单组是完美的解决方案。菜单组允许您将菜单项分组到它们自己的强调标题下。

php
use App\Nova\Dashboards\Sales;
use App\Nova\License;
use App\Nova\Refund;
use Illuminate\Http\Request;
use Laravel\Nova\Menu\MenuGroup;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Menu\MenuSection;

MenuSection::make('Business', [
    MenuGroup::make('Licensing', [
        MenuItem::dashboard(Sales::class),
        MenuItem::resource(License::class),
        MenuItem::resource(License::class),
        MenuItem::externalLink('Stripe Payments', 'https://dashboard.stripe.com/payments?status%5B%5D=successful'),
    ]),
]),

可折叠菜单组

您可以在组上调用 collapsable 方法,使您的菜单组可折叠。为了方便起见,Nova 会在请求之间记住该组的打开状态。

php
MenuGroup::make('Resources', [
    //
])->collapsable()

菜单项代表不同类型的链接,这些链接指向应用程序内部和外部的区域,可以添加到自定义 Nova 菜单中。Nova 附带了一些方便的方法,用于创建不同类型的菜单项。

首先,要创建指向 Nova 内部区域的链接,您可以在 MenuItem 类上调用 link 工厂方法。

php
use Laravel\Nova\Menu\MenuItem;

MenuItem::link('Cashier', '/cashier')

资源菜单项

由于您经常会创建指向 Nova 资源的链接,您可以使用resource方法快速创建指向给定资源的适当路径的链接。

php
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;

MenuItem::resource(User::class)

过滤后的资源菜单项

要创建指向具有预定义过滤器应用的 Nova 资源的链接,您可以使用 filter 方法,传入过滤器实例及其应接收的值。由于过滤器可以与多个资源一起使用,因此您还必须为菜单项传递一个名称,因为它无法自动生成。

php
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
use \App\Nova\Filters\NameFilter;

MenuItem::filter('Filtered Users', User::class, NameFilter::make(), 'Hemp');

使用多个过滤器与过滤后的资源菜单项

您还可以将多个过滤器传递给资源菜单项。例如,假设您想创建一个链接到 User 资源的菜单项,显示电子邮件以 @laravel.com 结尾且状态为 active 的用户。

php
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
use \App\Nova\Filters\EmailFilter;
use \App\Nova\Filters\StatusFilter;

MenuItem::filter('Filtered Users', User::class)
    ->applies(EmailFilter::make(), '@laravel.com')
    ->applies(StatusFilter::make(), 'active');

将构造函数参数传递给过滤后的资源菜单项

Nova 过滤器也可以接收构造函数参数,以便在资源之间方便地重复使用您的过滤器。要创建过滤后的资源菜单项时传递参数,只需将它们提供给过滤器的 make 方法。

php
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;
use App\Nova\Filters\ColumnFilter;

MenuItem::filter('Active Laravel Users', User::class)
    ->applies(ColumnFilter::make('name'), 'Hemp');

Lens 菜单项

与资源项类似,您可以通过 lens 方法创建指向 Nova 透镜的链接。

php
use App\Nova\Lenses\MostValuableUsers;
use App\Nova\User;
use Laravel\Nova\Menu\MenuItem;

MenuItem::lens(User::class, MostValuableUsers::class)

仪表板菜单项

您还可以通过调用 dashboard 工厂方法创建指向任何 自定义 Nova 仪表板 的链接。

php
use App\Nova\Dashboards\Main;
use Laravel\Nova\Menu\MenuItem;

MenuItem::dashboard(Main::class)

要创建将用户引导到 Nova 应用程序之外的某个位置的链接,您可以使用 externalLink 工厂方法。

php
use Laravel\Nova\Menu\MenuItem;

MenuItem::externalLink('Documentation', 'https://nova.laravel.net.cn/docs')

要指定外部链接应在单独的选项卡中打开,您可以在菜单项上调用 openInNewTab 方法。

php
MenuItem::externalLink('Documentation', 'https://nova.laravel.net.cn/docs')->openInNewTab();

您还可以调用 method 帮助程序来传入 HTTP 方法、请求数据以及单击链接时应发送到应用程序的任何 HTTP 标头。这通常对像注销链接这样的项目很有用,这些项目应该是 POST 请求。

php
use Laravel\Nova\Menu\MenuItem;

MenuItem::externalLink('Logout', 'https://api.yoursite.com/logout')
    ->method(
        'POST',
        data: ['user' => 'hemp'],
        headers: ['API_TOKEN' => 'abcdefg1234567']
    )

您可以通过在 MenuItem 上调用 withBadge 方法并指定徽章的选项来向菜单项添加视觉徽章。

php
use App\Nova\Dashboards\Issue;
use Laravel\Nova\Menu\MenuItem;
use Laravel\Nova\Badge;

// Passing a string directly
MenuItem::dashboard(Issue::class)
    ->withBadge('New!', 'info')

// Passing a Laravel\Nova\Badge instance directly
MenuItem::dashboard(Issue::class)
    ->withBadge(Badge::make('New!', 'info'))

// Using a closure to resolve the value
MenuItem::dashboard(Issue::class)
    ->withBadge(fn() => 13, 'danger')

条件徽章

您也可以仅在满足条件时才添加徽章。

php
use App\Nova\Issue;
use Laravel\Nova\Menu\MenuItem;

// Passing a string directly
MenuItem::resource(Issue::class)
    ->withBadgeIf('New!', 'info', fn() => Issue::newModel()->count() > 0)

// Passing a Laravel\Nova\Badge instance directly
MenuItem::resource(Issue::class)
    ->withBadgeIf(Badge::make('New!', 'info'), fn() => Issue::newModel()->count() > 0)

// Using a closure to resolve the value
MenuItem::resource(Issue::class)
    ->withBadgeIf(fn() => 'New!', 'info', fn() => Issue::newModel()->count() > 0)

授权菜单项

您可以使用 canSee 方法来确定是否应为当前经过身份验证的用户显示菜单项。

php
MenuItem::link('Cashier', '/cashier')
    ->canSee(function (NovaRequest $request) {
        return $request->user()->can('manageCashier');
    })