Обчислювана властивість - метод з атрибутом #[Computed], до якого звертаються як до властивості. Результат кешується в межах одного запиту.
use Livewire\Attributes\Computed;
new class extends Component {
public string $search = '';
#[Computed]
public function users()
{
return User::query()
->where('name', 'like', "%{$this->search}%")
->with('team')
->limit(20)
->get();
}
};
@foreach ($this->users as $user)
<li wire:key="{{ $user->id }}">{{ $user->name }} ({{ $user->team->name }})</li>
@endforeach
<p>Знайдено: {{ $this->users->count() }}</p> {{-- повторний доступ - без нового запиту --}}
У шаблоні - лише через $this->: $this->users, а не $users.
Чим краще за публічну властивість (public $users заповнена в mount()):
- не потрапляє в знімок стану - не їде в браузер і назад з кожним запитом;
- не перезавантажується з бази на кожен запит гідрації - лише коли шаблон чи код справді звертається до неї;
- завантажені зв'язки (
with('team')) працюють, бо запит виконується повністю щоразу, а не відновлюється за ключами; - завжди актуальна - похідна від поточного стану (
$search), її не треба оновлювати вручну.
Ліниве виконання - головна перевага: якщо дані потрібні лише в гілці @if, запит виконається лише тоді, коли умова істинна. А в острівці - лише коли рендериться саме острівець.
Скинути кеш у межах запиту, якщо дані змінилися:
public function addUser(): void
{
User::create([...]);
unset($this->users); // наступне звернення виконає запит заново
}
Кешування між запитами - #[Computed(persist: true)] (на компонент, година за замовчуванням) чи #[Computed(cache: true)] (спільно для всіх екземплярів) - але з обережністю щодо персональних даних.
Правило: публічні властивості - для стану, який змінює користувач (фільтри, введені значення, обраний id). Дані, що з них виводяться, - обчислювані властивості.