04. 显示 Chirps
在前面的步骤中,我们添加了创建 Chirps 的功能,现在我们准备显示它们!
检索 Chirps
首先,我们应该更新我们的 resources/views/chirps.blade.php
视图以显示 Chirps 列表。为此,我们可以使用一个新的 Livewire 组件
<x-app-layout> <div class="max-w-2xl mx-auto p-4 sm:p-6 lg:p-8"> <livewire:chirps.create />+ + <livewire:chirps.list /> </div> </x-app-layout>
然后,让我们创建一个新的 chirps.list
Livewire 组件
php artisan make:volt chirps/list --class
php artisan make:volt chirps/list
这将在 resources/views/livewire/chirps/list.blade.php
中创建一个新的 Livewire 组件。让我们更新 Livewire 组件以显示我们的 Chirps 列表
<?php +use App\Models\Chirp; +use Illuminate\Database\Eloquent\Collection; use Livewire\Volt\Component; new class extends Component {+ public Collection $chirps; + + public function mount(): void+ {+ $this->chirps = Chirp::with('user')+ ->latest()+ ->get();+ } }; ?> -<div> - // +<div class="mt-6 bg-white shadow-sm rounded-lg divide-y"> + @foreach ($chirps as $chirp)+ <div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}">+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">+ <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />+ </svg>+ <div class="flex-1">+ <div class="flex justify-between items-center">+ <div>+ <span class="text-gray-800">{{ $chirp->user->name }}</span>+ <small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small>+ </div>+ </div>+ <p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p>+ </div>+ </div>+ @endforeach </div>
<?php +use App\Models\Chirp; use function Livewire\Volt\{state}; +state(['chirps' => fn () => Chirp::with('user')->latest()->get()]); ?> -<div> - // +<div class="mt-6 bg-white shadow-sm rounded-lg divide-y"> + @foreach ($chirps as $chirp)+ <div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}">+ <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">+ <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" />+ </svg>+ <div class="flex-1">+ <div class="flex justify-between items-center">+ <div>+ <span class="text-gray-800">{{ $chirp->user->name }}</span>+ <small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small>+ </div>+ </div>+ <p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p>+ </div>+ </div>+ @endforeach </div>
在这里,我们使用了 Eloquent 的 with
方法来 预加载 每个 Chirp 关联的用户。我们还使用了 latest
作用域来按逆时间顺序返回记录。
一次性返回所有 Chirps 在生产环境中无法扩展。查看 Laravel 的强大 分页 功能以提高性能。
最后,每次创建新的 Chirp 时,都需要更新 Chirps 列表。我们可以使用 Livewire 事件 来实现。让我们在每次创建新的 Chirp 时分派一个事件
<?php
use Livewire\Attributes\Validate; use Livewire\Volt\Component; new class extends Component { #[Validate('required|string|max:255')] public $message = ''; public function store(): void { $validated = $this->validate(); auth()->user()->chirps()->create($validated); $this->message = '';+ + $this->dispatch('chirp-created'); } }; ?> <div>
<form wire:submit="store"> <textarea wire:model="message" placeholder="{{ __('What\'s on your mind?') }}" class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" /> <x-input-error :messages="$errors->get('message')" class="mt-2" /> <x-primary-button class="mt-4">{{ __('Chirp') }}</x-primary-button> </form> </div>
<?php
use function Livewire\Volt\{state}; use function Livewire\Volt\{rules, state}; state(['message' => '']); rules(['message' => 'required|string|max:255']); $store = function () { $validated = $this->validate(); auth()->user()->chirps()->create($validated); $this->message = '';+ + $this->dispatch('chirp-created'); }; ?> <div>
<form wire:submit="store"> <textarea wire:model="message" placeholder="{{ __('What\'s on your mind?') }}" class="block w-full border-gray-300 focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 rounded-md shadow-sm" /> <x-input-error :messages="$errors->get('message')" class="mt-2" /> <x-primary-button class="mt-4">{{ __('Chirp') }}</x-primary-button> </form> </div>
现在,我们可以更新我们的 `chirps.list` 组件来监听 `chirp-created` 事件,并更新 Chirps 列表。
<?php use App\Models\Chirp; use Illuminate\Database\Eloquent\Collection;+use Livewire\Attributes\On; use Livewire\Volt\Component; new class extends Component { public Collection $chirps; public function mount(): void {- $this->chirps = Chirp::with('user') - ->latest()- ->get(); + $this->getChirps(); }+ + #[On('chirp-created')]+ public function getChirps(): void+ {+ $this->chirps = Chirp::with('user')+ ->latest()+ ->get();+ } }; ?> <div class="mt-6 bg-white shadow-sm rounded-lg divide-y">
@foreach ($chirps as $chirp) <div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}"> <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /> </svg> <div class="flex-1"> <div class="flex justify-between items-center"> <div> <span class="text-gray-800">{{ $chirp->user->name }}</span> <small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small> </div> </div> <p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p> </div> </div> @endforeach </div>
<?php use App\Models\Chirp;-use function Livewire\Volt\{state}; +use function Livewire\Volt\{on, state}; -state(['chirps' => Chirp::with('user')->latest()->get()]); +$getChirps = fn () => $this->chirps = Chirp::with('user')->latest()->get(); + +state(['chirps' => $getChirps]);+ +on(['chirp-created' => $getChirps]); ?> <div class="mt-6 bg-white shadow-sm rounded-lg divide-y">
@foreach ($chirps as $chirp) <div class="p-6 flex space-x-2" wire:key="{{ $chirp->id }}"> <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-600 -scale-x-100" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"> <path stroke-linecap="round" stroke-linejoin="round" d="M8 12h.01M12 12h.01M16 12h.01M21 12c0 4.418-4.03 8-9 8a9.863 9.863 0 01-4.255-.949L3 20l1.395-3.72C3.512 15.042 3 13.574 3 12c0-4.418 4.03-8 9-8s9 3.582 9 8z" /> </svg> <div class="flex-1"> <div class="flex justify-between items-center"> <div> <span class="text-gray-800">{{ $chirp->user->name }}</span> <small class="ml-2 text-sm text-gray-600">{{ $chirp->created_at->format('j M Y, g:i a') }}</small> </div> </div> <p class="mt-4 text-lg text-gray-900">{{ $chirp->message }}</p> </div> </div> @endforeach </div>
将用户连接到 Chirps
我们已经指示 Laravel 返回 `user` 关系,以便我们可以显示 Chirp 作者的姓名。但是,Chirp 的 `user` 关系尚未定义。为了解决这个问题,让我们在 `Chirp` 模型中添加一个新的 "属于" 关系。
<?php
namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model;+use Illuminate\Database\Eloquent\Relations\BelongsTo; class Chirp extends Model {
use HasFactory; protected $fillable = [ 'message', ]; + public function user(): BelongsTo+ {+ return $this->belongsTo(User::class);+ } }
这种关系是我们之前在 `User` 模型中创建的“一对多”关系的逆关系。
现在看看你的浏览器,看看你之前 Chirped 的消息!
随意 Chirping 更多,甚至注册另一个帐户并开始对话!