媒体库 Pro:Vue、React 和 Blade 组件,用于处理上传(赞助)

发布时间 作者:

Media Library Pro: Vue, React and Blade components to handle uploads (sponsor) image

我很自豪地宣布 媒体库 Pro 现已推出。媒体库 Pro 是 我们免费的媒体库基础包 的附加软件包。它包含一组 BladeVueReact 组件,可以轻松地将文件上传到媒体库,并管理媒体库集合中的文件。

在本博文中,我想向大家介绍媒体库 Pro。

了解 Laravel 媒体库

在开始了解 Pro 组件之前,让我们先了解一下 免费版媒体库 可以为您做什么。如果您已经熟悉免费版媒体库,可以跳过此部分。

简而言之,媒体库可以将文件与 Eloquent 模型关联。例如,您可以将图像与博客文章模型关联。

$blogPost
->addMedia($pathToFile)
->toMediaCollection('images');

在您的 Blade 视图中,您可以检索与关联图像的 URL。

@foreach($blogPost->getMedia('images') as $mediaItem)
<img src="{{ $mediaItem->getUrl() }}" alt="my image" />
@endforeach

媒体库还可以生成各种转换。使用博客文章示例,您可能不希望在博客文章列表中显示原始图像。您更有可能希望在 such a list 上显示图像的较小版本(缩略图)。

您可以通过在模型上定义转换来让媒体库生成转换后的图像。以下是在 BlogPost 模型中可以添加的转换。

// somehwere in the BlogPost model
 
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(300)
->height(300)
->sharpen(10);
}

有了这些,媒体库将生成一个适合 300×300 方格的缩略图。图像也会略微锐化,因此看起来很清晰。当然,该缩略图将比原始图像小很多。您可以使用转换的名称作为 getUrl 的参数来获取转换的 URL。

@foreach($blogPost->getMedia('images') as $mediaItem)
<img src="{{ $mediaItem->getUrl('thumb') }}" alt="my thumbnail" />
@endforeach

在上面的示例中,我们定义了一个 thumb 转换,但您可以在模型中添加任意数量的转换。

媒体库还可以做更多事情。它可以 处理多个集合使用多个文件系统动态创建压缩包以下载多个文件、使用 自定义目录结构使用响应式图像节省带宽等等。

在这两段视频中,我向大家展示了 Laravel 媒体库的基础知识。

想观看更多类似的视频吗?查看我们的 关于如何使用 Laravel 媒体库的免费视频课程

传统上传的问题

在探索媒体库 Pro 之前,让我们先解释一下我们为什么要构建它。以下是传统上传表单可能的样子。它使用一个常规的 input 类型为 file

以下是渲染该表单的 Blade 视图。它取自 此演示应用程序

<form method="POST" enctype="multipart/form-data">
<x-grid>
@csrf
 
<x-field label="name">
<x-input id="name" name="name" placeholder="Your first name" />
</x-field>
 
<x-field label="file">
<input type="file" name="file">
@error('file')
{{ $message }}
@enderror
</x-field>
 
<x-button dusk="submit">Submit</x-button>
</x-grid>
</form>

此标准上传元素存在两个主要问题。

首先,上传过程仅在提交表单时开始。对于小型表单中的小型文件,这可能不是问题。但想象一下,您要在一个表单中上传一个多 MB 的文件。提交表单时,您现在必须等待上传完成才能看到提交结果。

第二个问题是,长期以来一直困扰着我。想象一下,输入字段是表单的一部分,该表单的一些字段是必需的。您正在选择一个文件,提交表单,留下一些必需字段为空。您被重定向回表单,现在显示了错误消息。您之前的文件选择消失了,您需要再次选择文件。多年来,每次发生这种情况时,我都会说很多脏话。

我敢肯定,作为一名开发人员,您可能在调试上传时浪费了时间,因为您忘记了在表单中添加 enctype="multipart/form-data"

在本视频中,您将看到所有这些问题的演示。

让我们看看 媒体库 Pro 如何解决所有这些问题。

介绍媒体库 Pro

媒体库 Pro 是一个付费的附加软件包,它提供 Blade、Vue 和 React 组件,用于将文件上传到您的应用程序。它附带两个组件。第一个是附件组件。它旨在用于面向公众的页面,您希望用户在该页面上上传一个或多个文件。

第二个称为集合组件。该组件可以管理现有集合中的文件。它旨在用于应用程序的管理部分。

这两个组件都提供 VueReactBlade 组件。在幕后,Blade 组件由 Caleb 的出色 Livewire 软件包 提供支持。

这些组件安装简单,并且 文档齐全

让我们看看 AttachmentCollection 组件。在博文的剩余部分,我将使用 Blade 版本的示例,但请放心,所有显示的内容也可以使用 Vue 和 React 对应部分完成。

附件组件

如果您想快速演示附件组件,请查看此视频。

您可以在 GitHub 上的此仓库 中找到视频中使用的代码。所有后续的代码示例都取自该应用程序。

要开始使用 Attachment Blade 组件,您需要在 您的视图 中使用 x-media-library-attachment

<form method="POST">
@csrf
 
<input id="name" name="name">
 
<x-media-library-attachment name="avatar"/>
 
<button type="submit">Submit</button>
</form>

以下是我们在选择文件但未提交表单之前的样子。

x-media-library-attachment 已经处理了上传。该文件现在存储为临时上传。如果提交表单时出现验证错误,x-media-library-attachment 将在您被重定向回表单时显示临时上传。用户无需再次上传文件。

以下是 用于验证上传的表单请求

namespace App\Http\Requests\Blade;
 
use Illuminate\Foundation\Http\FormRequest;
use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia;
 
class StoreBladeAttachmentRequest extends FormRequest
{
use ValidatesMedia;
 
public function rules()
{
return [
'name' => 'required',
'media' => ['required', $this->validateSingleMedia()
->maxItemSizeInKb(3000),
],
];
}
}

通过应用 ValidatesMedia 特性,您可以访问 validateSingleMedia,它允许您验证上传。您可以链接多个验证方法,这些方法在 此处 有文档记录。

在您的控制器中,您可以将上传文件与您想要的任何模型关联。

$formSubmission
->addFromMediaLibraryRequest($request->media)
->toMediaCollection('images');

这就是您需要做的全部!

附件组件也可以用于处理多个上传。在本视频中,您将看到如何操作。

集合组件

您可以使用 `x-media-library-collection` 组件管理媒体库集合的全部内容。此组件旨在用于管理部分。

以下是一个示例,我们将管理 `$formSubmission` 模型的 `images` 集合。

<form method="POST">
@csrf
<x-field label="name">
<x-input id="name" name="name" autocomplete="off" placeholder="Your name"
value="{{ old('name', $formSubmission->name) }}"/>
</x-field>
 
<x-field label="Images">
<x-media-library-collection
name="images"
:model="$formSubmission"
collection="images"
max-items="3"
rules="mimes:png,jpeg"
/>
</x-field>
 
<x-button dusk="submit" type="submit">Submit</x-button>
</form>

以下是该组件的示例:

此组件将显示整个集合的内容。可以添加、删除、更新和重新排序文件。

在这个视频中,您将看到集合组件的实际应用。

为了验证表单的响应,可以使用这样的表单请求:

namespace App\Http\Requests\Blade;
 
use Illuminate\Foundation\Http\FormRequest;
use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia;
 
class StoreBladeCollectionRequest extends FormRequest
{
use ValidatesMedia;
 
public function rules()
{
return [
'name' => 'required',
'images' => [$this->validateMultipleMedia()
->maxItems(3)
->itemName('required'),
],
];
}
}

同样,您需要使用 `ValidatesMedia` 特性。这次应该使用 `validateMultipleMedia`。您可以在其他验证方法上进行链接,这些方法在 此处 有文档记录。

在控制器中,您可以使用 `syncFromMediaLibraryRequest` 方法将集合组件中的媒体与您的模型关联起来。

以下是在 演示应用程序的控制器 中的相关代码。

$formSubmission
->syncFromMediaLibraryRequest($request->images)
->toMediaCollection('images');

添加自定义属性

使用集合组件时,您可能希望添加一些额外的字段以供显示。我们已经让这件事变得非常简单。

在下面的屏幕截图中,我们添加了 `Extra field` 字段。

您可以通过将 blade 视图传递到 `x-media-library-collection` 的 `fields-view` 属性 来实现这一点。

<x-media-library-collection
name="images"
:model="$formSubmission"
collection="images"
max-items="3"
rules="mimes:png,jpeg"
fields-view="uploads.blade.partials.custom-properties"
/>

在该 `custom-properties` 视图中,您可以放置任何应该在 `collection component` 右半部分显示的内容。

以下是 该 `custom-properties` 视图 的内容。

@include('media-library::livewire.partials.collection.fields')
 
<div class="media-library-field">
<label class="media-library-label">Extra field</label>
<input
dusk="media-library-extra-field"
class="media-library-input"
type="text"
{{ $mediaItem->customPropertyAttributes('extra_field') }}
/>
 
@error($mediaItem->customPropertyErrorName('extra_field'))
<span class="media-library-text-error">
{{ $message }}
</span>
@enderror
</div>

表单请求 中,您可以使用 `customProperty` 来验证任何额外的自定义属性。该函数的第二个参数可以接受 Laravel 中的任何验证器。

namespace App\Http\Requests\Blade;
 
use Illuminate\Foundation\Http\FormRequest;
use Spatie\MediaLibraryPro\Rules\Concerns\ValidatesMedia;
 
class StoreBladeCollectionCustomPropertyRequest extends FormRequest
{
use ValidatesMedia;
 
public function rules()
{
return [
'name' => 'required',
'images' => [$this->validateMultipleMedia()
->maxItems(3)
->itemName('required|max:30')
->customProperty('extra_field', 'required|max:30'),
],
];
}
}

处理表单提交的控制器 中,您应该使用 `withCustomProperties` 方法来白名单您想要与媒体同步的任何额外属性。

$formSubmission
->syncFromMediaLibraryRequest($request->images)
->withCustomProperties('extra_field')
->toMediaCollection('images');

以下是一个视频,您将在其中看到所有这些操作的实际应用。

自定义外观和感觉

默认情况下,`Attachment` 和 `Collection` 组件看起来都很好。您可能希望调整它们以匹配应用程序的外观。

幸运的是,这很容易做到。Media Library Pro 附带的样式可以通过导入或链接 `dist/styles.css` 来使用。这些样式是用默认的 `tailwind.config.js` 构建的。

您可以通过导入 `src/styles.css` 并运行每个 `@apply` 规则来自定义样式,这些规则通过您自己的 `tailwind.config.js` 运行。

/* app.css */
 
@tailwind base;
 
@tailwind components;
 
@tailwind utilities;
 
@import "src/styles.css";
 

要查看此操作的实际应用,请观看此视频。

临时文件的使用方式

为了实现上传文件在表单验证错误发生时仍然保留的行为,我们使用临时上传。在这个视频中,我解释了它是如何工作的。

测试组件

私有的 spatie/laravel-medialibrary-pro 仓库 中,有很多测试来确保后端集成以及 Vue、React 和 Blade 前端组件按预期工作。

我们还希望进行浏览器测试,以确保前端组件与后端完美配合,反之亦然。这就是我们在演示应用程序中添加 Dusk 测试的原因。您可以在 此处 查看它们。

让我们看一下 其中之一

/**
* @test
*
* @dataProvider routeNames
*/
public function it_can_handle_a_single_upload(string $routeName)
{
$this->browse(function (Browser $browser) use ($routeName) {
$browser
->visit(route($routeName))
->type('name', 'My name')
->attach('@main-uploader', $this->getStubPath('space.png'))
->waitForText('Remove')
->waitUntilMissing('.media-library-progress-wrap.media-library-progress-wrap-loading')
->press('@submit')
->assertSee('Your form has been submitted');
 
$this->assertCount(1, FormSubmission::get());
 
$this->assertEquals('space.png', FormSubmission::first()->getFirstMedia('images')->file_name);
});
}

此测试将上传一个文件,并确保在提交表单后该文件与模型关联起来。

这里要注意的是 `@dataProvider` 属性。这将使 PHPUnit 对 `routeNames` 函数返回的每个结果运行测试,该函数在同一文件中的 定义

public function routeNames(): array
{
return [
['vue.attachment'],
['react.attachment'],
['blade.attachment'],
];
}

您可以看到,与 `routeNames` 函数结合使用,`it_can_handle_a_single_upload` 将针对 `vue.attachment`、`react.attachment` 和 `blade.attachment` 路由运行。访问这些路由将分别显示使用 Vue、React 或 Blade 组件的表单。因此,此测试涵盖了许多逻辑。它确保该组件使用任何技术都可以正常工作。这让我们对所有组件都正常工作充满信心。

另一个值得注意的是,Dusk 测试也在 GitHub Actions 上运行。以下是仓库中包含的 工作流

最后

在我看来,这些前端组件是媒体库体验中缺失的最后一块拼图。我很高兴它们最终的效果以及现在在 Laravel 应用程序中上传和管理媒体变得多么容易。

由于我们在使这些组件完美无缺方面投入了相当多的时间,我们决定将 spatie/laravel-media-library-pro 作为付费软件包。您可以在我们的网站上 购买许可证。如前所述,该软件包包含 Blade、Vue 和 React 组件。您将在此处找到详细的文档。

购买许可证后,您将立即获得访问 私有的 spatie/laravel-medialibrary-pro 仓库 的权限。即使您没有购买强大的上传组件的计划,购买它们仍然可能值得:源代码包含许多您可以从中学习的有趣内容。

在撰写本文时,我们正在进行发布促销活动。在 购买 Media Library Pro 时使用此优惠券代码,可享受 20% 的折扣。

MEDIA-LIBRARY-PRO-IS-HERE

我们的整个团队都对这些组件提出了意见,因此我认为这是团队合作的结果。我的同事 Adriaan 编写了大部分 JavaScript 代码。 Willem 总是让一切看起来都很漂亮。

对于那些想知道的人来说,基础媒体库软件包 仍然是免费的,我们也会永远保持免费。

务必查看 我们其他付费产品我们丰富的免费开源软件包集合

Freek Van der Herten photo

Spatie.be 的 PHP 开发人员、Laravel 爱好者、博主和软件包创建者。

归档于
Cube

Laravel 新闻

加入 40,000 多名其他开发者,绝不错过新的技巧、教程等。

Laravel Forge logo

Laravel Forge

轻松创建和管理您的服务器,并在几秒钟内部署您的 Laravel 应用程序。

Laravel Forge
Tinkerwell logo

Tinkerwell

Laravel 开发人员必备的代码运行器。使用 AI、自动完成和对本地和生产环境的即时反馈进行微调。

Tinkerwell
No Compromises logo

绝不妥协

Joel 和 Aaron 是来自 No Compromises 播客的两位经验丰富的开发者,现在可以为您的 Laravel 项目聘用。 ⬧ 每月固定价格 7500 美元。 ⬧ 无需冗长的销售流程。 ⬧ 无需合同。 ⬧ 100% 退款保证。

绝不妥协
Kirschbaum logo

Kirschbaum

提供创新和稳定性,确保您的 Web 应用程序成功。

Kirschbaum
Shift logo

Shift

正在运行旧版本的 Laravel?即时、自动化的 Laravel 升级和代码现代化,让您的应用程序保持新鲜感。

Shift
Bacancy logo

Bacancy

只需每月 2500 美元,即可让您的项目与拥有 4-6 年经验的资深 Laravel 开发人员合作。获得 160 小时的专职专业知识和 15 天的免费试用。立即安排电话会议!

Bacancy
Lucky Media logo

Lucky Media

立即获得好运 - Laravel 开发的理想选择,拥有超过十年的经验!

Lucky Media
Lunar: Laravel E-Commerce logo

Lunar:Laravel 电子商务

Laravel 的电子商务。一个开源软件包,将现代无头电子商务功能的力量带到 Laravel。

Lunar:Laravel 电子商务
LaraJobs logo

LaraJobs

官方 Laravel 工作板

LaraJobs
SaaSykit: Laravel SaaS Starter Kit logo

SaaSykit:Laravel SaaS 启动工具包

SaaSykit 是一个 Laravel SaaS 启动工具包,包含运行现代 SaaS 所需的所有功能。支付、漂亮的结账、管理面板、用户仪表板、身份验证、现成组件、统计、博客、文档等等。

SaaSykit:Laravel SaaS 启动工具包
Rector logo

Rector

您无缝升级 Laravel、降低成本和加速创新以帮助公司取得成功的合作伙伴

Rector
MongoDB logo

MongoDB

通过 MongoDB 和 Laravel 的强大集成增强您的 PHP 应用程序,使开发人员能够轻松高效地构建应用程序。在使用熟悉的 Eloquent API 的同时,支持事务性、搜索、分析和移动用例。探索 MongoDB 的灵活、现代数据库如何改变您的 Laravel 应用程序。

MongoDB
Maska is a Simple Zero-dependency Input Mask Library image

Maska 是一个简单的零依赖输入掩码库

阅读文章
Add Swagger UI to Your Laravel Application image

将 Swagger UI 添加到您的 Laravel 应用程序

阅读文章
Assert the Exact JSON Structure of a Response in Laravel 11.19 image

在 Laravel 11.19 中断言响应的精确 JSON 结构

阅读文章
Build SSH Apps with PHP and Laravel Prompts image

使用 PHP 和 Laravel 提示构建 SSH 应用程序

阅读文章
Building fast, fuzzy site search with Laravel and Typesense image

使用 Laravel 和 Typesense 构建快速、模糊的网站搜索

阅读文章
Add Comments to your Laravel Application with the Commenter Package image

使用 Commenter 软件包在您的 Laravel 应用程序中添加评论

阅读文章