Laravel Nova 字段

2023-02-16 17:09 更新

概述

Nova 提供了很多不同類型的字段;然而,有的時(shí)候你需要的字段 Nova 并不包含。 由于這個(gè)原因, Nova 允許你創(chuàng)建自定義字段。自定義的字段由三個(gè) Vue 組件構(gòu)成,這些組件決定了字段在不同的情景下將如何呈現(xiàn)。

定義字段

自定義字段可以用 nova:field Artisan 命令生成。默認(rèn)情況下,所有新的字段會(huì)被放在應(yīng)用程序的 nova-components 文件夾下。當(dāng)你使用 nova:field 命令生成新字段的時(shí)候,字段的命名應(yīng)該遵循 Composer vendor/package 格式。因此,如果我們創(chuàng)建一個(gè) color-picker 字段,我們可以執(zhí)行下面的命令:

php artisan nova:field acme/color-picker

當(dāng)生成一個(gè)新字段的時(shí)候,Nova 會(huì)提示你安裝字段的 NPM 依賴包,編譯它的資源,和更新應(yīng)用程序的 composer.json 文件。所有的自定義字段會(huì)被注冊(cè)為一個(gè) Composer 「path」 代碼庫(kù)。

Nova 字段包含了所有必要的腳手架去幫助你創(chuàng)建自己的字段。 每個(gè)字段甚至擁有它自己的 composer.json 文件,所以它可以在 github 或者其它源代碼控制平臺(tái)上直接地被分享。

注冊(cè)字段

Nova 字段可能被注冊(cè)在資源的 fields 方法中。這個(gè)方法會(huì)返回一個(gè)可以被資源讀取的字段數(shù)組。想要注冊(cè)你的字段,只需要把該字段加入到返回的數(shù)組中即可:

use Acme\ColorPicker\ColorPicker;

/**
 * 獲取被資源呈現(xiàn)的字段。
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function fields(Request $request)
{
    return [
        ID::make('ID', 'id')->sortable(),

        ColorPicker::make('Color'),
    ];
}

字段選項(xiàng)

通常,你將允許字段的使用者在運(yùn)行交互時(shí)能夠自定義配置選項(xiàng),這可以通過(guò)開(kāi)放字段類的方法來(lái)實(shí)現(xiàn)。這些方法會(huì)調(diào)用字段底層的 withMeta 方法將信息添加到元數(shù)據(jù)中,從而能夠在 Vue 組件中 被讀取withMeta 方法的參數(shù)為一組鍵 / 值選項(xiàng)的關(guān)聯(lián)數(shù)組:

<?php

namespace Acme\ColorPicker;

use Laravel\Nova\Fields\Field;

class ColorPicker extends Field
{
    /**
     * 字段的組件
     *
     * @var string
     */
    public $component = 'color-picker';

    /**
     * 設(shè)置選色器選中的色調(diào)
     *
     * @param  array  $hues
     * @return $this
     */
    public function hues(array $hues)
    {
        return $this->withMeta(['hues' => $hues]);
    }
}

創(chuàng)建字段

Nova 生成的每個(gè)字段都包含自己的服務(wù)提供者和「字段」類。以 color-picker 字段為例,它的類會(huì)被保存在:src/ColorPicker.php。

字段類的服務(wù)提供者同樣存儲(chǔ)在 src 文件夾下,并且在字段的 composer.json 文件中被注冊(cè),所以它會(huì)被 Laravel 自動(dòng)加載。

字段首頁(yè)

當(dāng) Nova 生成字段時(shí),它會(huì)創(chuàng)建一個(gè) resources/js/components/IndexField.vue Vue 組件。這個(gè)組件包含了該字段在資源首頁(yè)被顯示時(shí)所需要的模版和邏輯。默認(rèn)情況下,這個(gè)組件僅在 <span> 元素中簡(jiǎn)單地輸出了字段的值;然而,你可以隨意按需編輯該組件。

字段頁(yè)面

當(dāng)字段被生成時(shí),Nova 同樣會(huì)創(chuàng)建一個(gè) resources/js/components/DetailField.vue Vue 組件。這個(gè)組件包含了該字段在資源頁(yè)面被顯示時(shí)所需要的模版和邏輯。默認(rèn)情況下,這個(gè)模版包含了必要的元素去顯示所有字段的值。然而,你可以按照你的項(xiàng)目需求隨意更新這個(gè)模版。

字段表格

最后,Nova 還創(chuàng)建了一個(gè) resources/js/components/FormField.vue Vue 組件。這個(gè)組件包含了創(chuàng)建或者更新資源時(shí)所需要的模版和邏輯。默認(rèn)情況下,該模版包含了一個(gè)簡(jiǎn)單的 input 控制去更新字段的值;然而,你可以隨意自定義這個(gè)模版。舉個(gè)例子,我們可以在模版中加入一個(gè)選色器控制:

<template>
    <default-field :field="field">
        <template slot="field">
            <input :id="field.name" type="color"
                class="w-full form-control form-input form-input-bordered"
                :class="errorClasses"
                :placeholder="field.name"
                v-model="value"
            />

            <p v-if="hasError" class="my-2 text-danger">
                {{ firstError }}
            </p>
        </template>
    </default-field>
</template>

設(shè)置表單值

在創(chuàng)建或更新資源前,Nova 要求表單上的每個(gè)字段用鍵 / 值對(duì)填充傳出的 FormData 對(duì)象。每個(gè)字段可以根據(jù)需要添加任意數(shù)量的元素到 FormData。這可以在您的 FormField.vue 文件的  fill 方法中完成:

/**
 * 用字段內(nèi)部值填充給定的 FormData 對(duì)象
 */
fill(formData) {
  formData.append(this.field.attribute, this.value || '')
}

水合模型

默認(rèn)情況下,保存模型時(shí),字段類只會(huì)將傳入表單字段值復(fù)制到字段的關(guān)聯(lián)模型屬性中。但是,您可以自定義您的字段合并資源模型的方式。為此,請(qǐng)重寫(xiě)字段類的 fillAttributeFromRequest 方法:

<?php

namespace Otwell\ColorPicker;

use Laravel\Nova\Fields\Field;

class ColorPicker extends Field
{
    /**
     * 字段的組成部分。
     *
     * @var string
     */
    public $component = 'color-picker';

    /**
     * 根據(jù)傳入的請(qǐng)求水合模型上的給定屬性。
     *
     * @param  \Laravel\Nova\Http\Requests\NovaRequest  $request
     * @param  string  $requestAttribute
     * @param  object  $model
     * @param  string  $attribute
     * @return void
     */
    protected function fillAttributeFromRequest(NovaRequest $request,
                                                $requestAttribute,
                                                $model,
                                                $attribute)
    {
        if ($request->exists($requestAttribute)) {
            $model->{$attribute} = $request[$requestAttribute];
        }
    }
}

此方法接收你個(gè)參數(shù)。當(dāng)然,它接收傳入的 HTTP 請(qǐng)求和正在更新的模型。該方法還接收 $requestAttribute,他是 HTTP 請(qǐng)求中傳入表單字段的名稱。此外,它還接收 $attribute,這是字段值放置在其中的模型屬性的名稱。

Assets

當(dāng) Nova 生成您的字段時(shí),會(huì)為您生成 resources/js 和 resources/sass 目錄。這些目錄包含您字段的 JavaScript 和 Sass 樣式表。

字段屬性

您字段的 Vue 組件接收一個(gè) field Vue prop。field 屬性提供對(duì)任何可用字段 options 的訪問(wèn)。

const hues = this.field.hues;

注冊(cè) Assets

您 Nova 字段的服務(wù)提供注冊(cè)您字段編譯的 assets,以便他們可供 Nova 前端使用:

/**
 * 引導(dǎo)任何應(yīng)用程序服務(wù)。
 *
 * @return void
 */
public function boot()
{
    Nova::serving(function (ServingNova $event) {
        Nova::script('stripe-inspector', __DIR__.'/../dist/js/field.js');
        Nova::style('stripe-inspector', __DIR__.'/../dist/css/field.css');
    });
}

JavaScript 引導(dǎo) & 路由

您的組件已引導(dǎo)并在 resources/js/field.js 文件中注冊(cè)。您可以根據(jù)需要自由修改此文件或在此處注冊(cè)其它組件。

編譯資源

Nova 生成字段的同時(shí)也為其創(chuàng)建了一個(gè) webpack.mix.js 文件。你可以使用 NPM dev 和 prod 命令編譯字段:

// 在本地開(kāi)發(fā)環(huán)境編譯資源...
npm run dev

// 編譯并壓縮資源...
npm run prod

此外,你可以運(yùn)行 NPM watch 命令來(lái)實(shí)現(xiàn)文件改動(dòng)后的自動(dòng)編譯:

npm run watch


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)