主题
文件下载
Livewire 中的文件下载与 Laravel 本身的工作方式大致相同。通常,你可以在 Livewire 组件内使用任何 Laravel 下载实用程序,它应该按预期工作。
但是,在幕后,文件下载的处理方式与标准 Laravel 应用程序不同。使用 Livewire 时,文件内容被 Base64 编码,发送到前端,然后解码回二进制,直接从客户端下载。
基本用法
在 Livewire 中触发文件下载就像返回标准 Laravel 下载响应一样简单。
以下是一个 show-invoice 组件的示例,其中包含一个"Download"按钮来下载发票 PDF:
php
<?php // resources/views/components/⚡show-invoice.blade.php
use Livewire\Component;
use App\Models\Invoice;
new class extends Component
{
public Invoice $invoice;
public function mount(Invoice $invoice)
{
$this->invoice = $invoice;
}
public function download()
{
return response()->download( // [tl! highlight:2]
$this->invoice->file_path, 'invoice.pdf'
);
}
};blade
<div>
<h1>{{ $invoice->title }}</h1>
<span>{{ $invoice->date }}</span>
<span>{{ $invoice->amount }}</span>
<button type="button" wire:click="download">Download</button> <!-- [tl! highlight] -->
</div>就像在 Laravel 控制器中一样,你也可以使用 Storage facade 来启动下载:
php
public function download()
{
return Storage::disk('invoices')->download('invoice.csv');
}流式下载
Livewire 也可以流式下载;但是,它们并非真正的流式传输。在文件内容被收集并传递到浏览器之前,不会触发下载:
php
public function download()
{
return response()->streamDownload(function () {
echo '...'; // Echo download contents directly...
}, 'invoice.pdf');
}测试文件下载
Livewire 还提供了 ->assertFileDownloaded() 方法来轻松测试文件是否以给定名称下载:
php
use App\Models\Invoice;
public function test_can_download_invoice()
{
$invoice = Invoice::factory();
Livewire::test(ShowInvoice::class)
->call('download')
->assertFileDownloaded('invoice.pdf');
}你还可以使用 ->assertNoFileDownloaded() 方法测试以确保文件未被下载:
php
use App\Models\Invoice;
public function test_does_not_download_invoice_if_unauthorised()
{
$invoice = Invoice::factory();
Livewire::test(ShowInvoice::class)
->call('download')
->assertNoFileDownloaded();
}