Skip to content

下载

Livewire 中的文件下载与 Laravel 本身的工作方式大致相同。通常,你可以在 Livewire 组件中使用任何 Laravel 下载工具,它应该按预期工作。

然而,在幕后,文件下载的处理方式与标准 Laravel 应用程序不同。使用 Livewire 时,文件内容会被 Base64 编码,发送到前端,然后解码回二进制以直接从客户端下载。

基本用法

在 Livewire 中触发文件下载就像返回标准 Laravel 下载响应一样简单。

下面是一个 show-invoice 组件的示例,其中包含一个"下载"按钮来下载发票 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(
            $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">下载</button>
</div>

就像在 Laravel 控制器中一样,你也可以使用 Storage 门面来启动下载:

php
public function download()
{
    return Storage::disk('invoices')->download('invoice.csv');
}

流式下载

Livewire 也可以流式下载;但是,它们并不是真正的流式传输。直到文件内容被收集并传送到浏览器后,下载才会触发:

php
public function download()
{
    return response()->streamDownload(function () {
        echo '...'; // 直接回显下载内容...
    }, '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();
}