Skip to content
全部文档

URL 查询参数

Livewire 允许你把组件属性存进 URL 的查询字符串。例如,你可能希望组件中的 $search 属性出现在 URL 里:https://example.com/users?search=bob。这对筛选、排序、分页等场景特别有用,因为用户可以分享和收藏页面的特定状态。

基本用法

下面是一个 show-users 组件,通过简单的文本输入按姓名搜索用户:

php
<?php // resources/views/components/⚡show-users.blade.php

use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\User;

new class extends Component {
    public $search = '';

    #[Computed]
    public function users()
    {
        return User::search($this->search)->get();
    }
};
blade
<div>
    <input type="text" wire:model.live="search">

    <ul>
        @foreach ($this->users as $user)
            <li wire:key="{{ $user->id }}">{{ $user->name }}</li>
        @endforeach
    </ul>
</div>

可以看到,由于文本输入使用了 wire:model.live="search",用户在输入时会发送网络请求来更新 $search 属性,并在页面上显示筛选后的用户列表。

不过,如果访问者刷新页面,搜索值和结果就会丢失。

为了在页面加载之间保留搜索值,让访问者可以刷新页面或分享 URL,可以在 $search 属性上方加上 #[Url] 属性,把搜索值存进 URL 的查询字符串,如下所示:

php
<?php // resources/views/components/⚡show-users.blade.php

use Livewire\Attributes\Computed;
use Livewire\Attributes\Url;
use Livewire\Component;
use App\Models\User;

new class extends Component {
    #[Url] // [tl! highlight]
    public $search = '';

    #[Computed]
    public function users()
    {
        return User::search($this->search)->get();
    }
};

现在,如果用户在搜索框中输入「bob」,浏览器地址栏会显示:

text
https://example.com/users?search=bob

如果他们在新的浏览器窗口中打开这个 URL,搜索框会填入「bob」,用户结果也会相应筛选。

从 URL 初始化属性

如上一示例所示,当属性使用 #[Url] 时,它不仅会把更新后的值存进 URL 的查询字符串,还会在页面加载时读取已有的查询字符串值。

例如,如果用户访问 URL https://example.com/users?search=bob,Livewire 会将 $search 的初始值设为「bob」。

php
use Livewire\Attributes\Url;
use Livewire\Component;

class ShowUsers extends Component
{
    #[Url]
    public $search = ''; // Will be set to "bob"...

    // ...
}

可空属性

默认情况下,如果页面带着空的查询字符串项(如 ?search=)加载,Livewire 会把该值当作空字符串。多数情况下这符合预期,但有时你希望把 ?search= 当作 null

这时,你可以使用可空类型提示,如下所示:

php
use Livewire\Attributes\Url;
use Livewire\Component;

class ShowUsers extends Component
{
    #[Url]
    public ?string $search; // [tl! highlight]

    // ...
}

由于上述类型提示中有 ?,Livewire 看到 ?search= 时会将 $search 设为 null,而不是空字符串。

反过来也一样:若在应用中设置 $this->search = null,查询字符串中会表示为 ?search=

使用别名

Livewire 让你可以完全控制 URL 查询字符串中显示的名称。例如,你可能有一个 $search 属性,但希望混淆真实属性名,或将其缩短为 q

可以通过向 #[Url] 属性提供 as 参数来指定查询字符串别名:

php
use Livewire\Attributes\Url;
use Livewire\Component;

class ShowUsers extends Component
{
    #[Url(as: 'q')]
    public $search = '';

    // ...
}

现在,当用户在搜索框中输入「bob」时,URL 会显示 https://example.com/users?q=bob,而不是 ?search=bob

排除特定值

默认情况下,Livewire 只会在值相对于初始化时发生变化时,才把该项写入查询字符串。多数时候这是期望行为,但在某些场景下,你可能希望更精细地控制哪些值要从查询字符串中排除。这时可以使用 except 参数。

例如,在下面的组件中,$search 的初始值在 mount() 中被修改。为确保浏览器仅在 search 为空字符串时才从查询字符串中排除 search,已在 #[Url] 上添加了 except 参数:

php
use Livewire\Attributes\Url;
use Livewire\Component;

class ShowUsers extends Component
{
    #[Url(except: '')]
    public $search = '';

    public function mount() {
        $this->search = auth()->user()->username;
    }

    // ...
}

若上例没有 except,只要 search 的值等于初始值 auth()->user()->username,Livewire 就会从查询字符串中移除 search。而使用了 except: '' 后,Livewire 会保留所有查询字符串值,仅在 search 为空字符串时排除。

页面加载时显示

默认情况下,Livewire 只有在页面上的值被更改后,才会在查询字符串中显示该值。例如,若 $search 的默认值是空字符串 "",当搜索输入实际为空时,URL 中不会出现该值。

如果希望即使值为空,?search 也始终出现在查询字符串中,可以向 #[Url] 属性提供 keep 参数:

php
use Livewire\Attributes\Url;
use Livewire\Component;

class ShowUsers extends Component
{
    #[Url(keep: true)]
    public $search = '';

    // ...
}

现在,页面加载时,URL 会变成:https://example.com/users?search=

存入历史记录

默认情况下,Livewire 使用 history.replaceState() 修改 URL,而不是 history.pushState()。这意味着更新查询字符串时,Livewire 会修改浏览器历史中的当前条目,而不是新增一条。

由于 Livewire「替换」当前历史记录,按下浏览器的「后退」按钮会回到上一页,而不是上一个 ?search= 值。

若要强制 Livewire 在更新 URL 时使用 history.pushState,可以向 #[Url] 属性提供 history 参数:

php
use Livewire\Attributes\Url;
use Livewire\Component;

class ShowUsers extends Component
{
    #[Url(history: true)]
    public $search = '';

    // ...
}

在上例中,当用户把搜索值从「bob」改成「frank」,再点击浏览器后退按钮时,搜索值(以及 URL)会恢复为「bob」,而不是导航到之前访问过的页面。

使用 queryString 方法

查询字符串也可以在组件上定义为方法。如果某些属性有动态选项,这会很有用。

php
use Livewire\Component;

class ShowUsers extends Component
{
    // ...

    protected function queryString()
    {
        return [
            'search' => [
                'as' => 'q',
            ],
        ];
    }
}

Trait 钩子

Livewire 也为查询字符串提供了钩子

php
trait WithSorting
{
    // ...

    protected function queryStringWithSorting()
    {
        return [
            'sortBy' => ['as' => 'sort'],
            'sortDirection' => ['as' => 'direction'],
        ];
    }
}

另见

  • 属性将属性与 URL 参数同步
  • 导航在 SPA 导航期间保持 URL 状态
  • Url 属性将属性绑定到 URL 查询字符串
  • 页面处理路由参数