主题
Session
#[Session] 属性在用户会话中持久化属性的值,在页面刷新和导航之间维护它。
基本用法
将 #[Session] 属性应用到任何应在会话中持久化的属性上:
php
<?php // resources/views/components/post/⚡index.blade.php
use Livewire\Attributes\Session;
use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Post;
new class extends Component
{
#[Session] // [tl! highlight]
public $search = '';
#[Computed]
public function posts()
{
return $this->search === ''
? Post::all()
: Post::where('title', 'like', "%{$this->search}%")->get();
}
};
?>
<div>
<input type="text" wire:model.live="search" placeholder="搜索帖子...">
@foreach($this->posts as $post)
<div>{{ $post->title }}</div>
@endforeach
</div>用户输入搜索值后,可以刷新页面或离开后返回——搜索值将被保留。
工作原理
每次属性更改时,Livewire 将其新值存储在用户的会话中。当组件加载时,Livewire 从会话中获取值并用它初始化属性。
这创建了持久的用户体验而不修改 URL。
Session 与 URL 的比较
#[Session] 和 #[Url] 都可以持久化属性值,但有不同的权衡:
| 功能 | #[Session] | #[Url] |
|---|---|---|
| 刷新后持久化 | ✅ | ✅ |
| 分享 URL时持久化 | ❌ | ✅ |
| 保持 URL 简洁 | ✅ | ❌ |
| 对用户可见 | ❌ | ✅ |
| 可分享状态 | ❌ | ✅ |
当您需要持久化而不杂乱 URL 或状态不应被分享时,请使用 #[Session]。
自定义会话键
默认情况下,Livewire 使用组件和属性名称生成会话键。您可以自定义它:
php
<?php // resources/views/components/post/⚡index.blade.php
use Livewire\Attributes\Session;
use Livewire\Component;
new class extends Component
{
#[Session(key: 'post_search')] // [tl! highlight]
public $search = '';
};属性将使用键 post_search 存储在会话中。
动态会话键
您可以使用其他属性动态生成键:
php
<?php // resources/views/components/post/⚡index.blade.php
use Livewire\Attributes\Session;
use Livewire\Component;
use App\Models\Author;
new class extends Component
{
public Author $author;
#[Session(key: 'search-{author.id}')] // [tl! highlight]
public $search = '';
};如果 $author->id 为 4,会话键将变为 search-4。这允许每个作者有不同的会话值。
何时使用
在以下情况下使用 #[Session]:
- 持久化用户偏好(主题、语言、侧边栏状态)
- 在页面导航中维护筛选/搜索状态
- 存储表单数据以防止刷新时丢失
- 保持 UI 状态对用户私密
- 避免查询参数杂乱 URL
示例:仪表板筛选器
以下是持久化仪表板筛选器的实际示例:
php
<?php // resources/views/pages/⚡dashboard.blade.php
use Livewire\Attributes\Session;
use Livewire\Attributes\Computed;
use Livewire\Component;
use App\Models\Transaction;
new class extends Component
{
#[Session]
public $dateRange = '30days';
#[Session]
public $category = 'all';
#[Session]
public $sortBy = 'date';
#[Computed]
public function transactions()
{
return Transaction::query()
->when($this->dateRange === '30days', fn($q) => $q->where('created_at', '>=', now()->subDays(30)))
->when($this->category !== 'all', fn($q) => $q->where('category', $this->category))
->orderBy($this->sortBy)
->get();
}
};
?>
<div>
<select wire:model.live="dateRange">
<option value="7days">最近 7 天</option>
<option value="30days">最近 30 天</option>
<option value="year">今年</option>
</select>
<select wire:model.live="category">
<option value="all">所有类别</option>
<option value="income">收入</option>
<option value="expense">支出</option>
</select>
<select wire:model.live="sortBy">
<option value="date">日期</option>
<option value="amount">金额</option>
</select>
@foreach($this->transactions as $transaction)
<div>{{ $transaction->description }}</div>
@endforeach
</div>用户可以设置他们偏好的筛选器,它们将在会话、页面刷新和导航之间持久化。
性能考虑
不要存储大量数据
Laravel 会话在每个请求期间加载到内存中。在用户会话中存储过多内容可能会为该用户减慢整个应用程序。避免存储大型集合或对象。
良好的用途:
- 简单值(字符串、数字、布尔值)
- 小数组(筛选选项、偏好设置)
- 模型 ID(而不是完整模型)
不良的用途:
- 大型集合
- 完整的 Eloquent 模型
- 二进制数据或文件内容
了解更多
有关会话属性和 URL 持久化等替代方法的更多信息,请参阅会话属性文档。