文件下载
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();
}