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)上直接地被分享。
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'),
];
}
通常,你將允許字段的使用者在運(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]);
}
}
Nova 生成的每個(gè)字段都包含自己的服務(wù)提供者和「字段」類。以 color-picker
字段為例,它的類會(huì)被保存在:src/ColorPicker.php
。
字段類的服務(wù)提供者同樣存儲(chǔ)在 src
文件夾下,并且在字段的 composer.json
文件中被注冊(cè),所以它會(huì)被 Laravel 自動(dòng)加載。
當(dāng) Nova 生成字段時(shí),它會(huì)創(chuàng)建一個(gè) resources/js/components/IndexField.vue
Vue 組件。這個(gè)組件包含了該字段在資源首頁(yè)被顯示時(shí)所需要的模版和邏輯。默認(rèn)情況下,這個(gè)組件僅在 <span>
元素中簡(jiǎn)單地輸出了字段的值;然而,你可以隨意按需編輯該組件。
當(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>
在創(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
,這是字段值放置在其中的模型屬性的名稱。
當(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;
您 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
更多建議: