原文地址 : Livewire-Blog (用 Laravel 8 + Jetstream 构建的一个开源博客)
背景
Laravel 8 发布近一个月了,这次改动比较吸引我的就是 Jetstream 全家桶。在没发布之前我没接触过 Livewire 以及前端的 Tailwindcss,alpinejs。但是我是一个比较喜欢尝试新技术的人。在商业化的项目去实践显然是不可取的。所以我在国庆开始的时候就打算利用假期的时间去折腾下博客试试,了解它的特点。再去项目中对应的去使用。经过一段时间的折腾我发现这玩意挺香的。当然也有一些坑,我也会分享出来。
Livewire-Blog
github 代码地址 喜欢的请star?下 ?
博客线上地址
PC端界面效果
移动端界面效果
功能分析
搜索案例
Livewire 最大的优点的就是跟前端界面动态交互,比如我搜索 Laravel 的时候他可以配合前端监听我的输入。实时通过 api 调用后台的数据返回给前端。而这些 api 是无须你在编写的。它的核心文件 LivewireServiceProvider
已经注册。有兴趣的同学可以看下这个核心文件。
php artisan make:livewire search
生成search.blade.php
Search.php
文件
search.blade.php
Search.php
查看效果
评论案例
评论里面会用到 Livewire
的组件全局事件相互通信
- 需求分析
代码实现
php artisan make:livewire AddComment
php artisan make:livewire ShowComment
AddComment
<?php
namespace App\Http\Livewire;
use App\Models\CommentModel;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\MessageBag;
use Illuminate\Support\Str;
use Illuminate\View\View;
use Livewire\Component;
class AddComment extends Component
{
/**
* @var string
*/
public $content;
/**
* @var int
*/
public $post_id;
/**
* @var int
*/
public $parent_id;
/**
* @var string
*/
public $comment_composing_box_id;
/**
* @var string
*/
public $preview_box_id;
/**
* @var string
*/
public $target_id;
/**
* @var array
*/
protected $rules = [
'content' => 'required',
];
/**
* @var array
*/
protected $messages = [
'content.required' => '评论不能为空!',
];
public function mount(int $postId, CommentModel $comment, int $time = 0): void
{
$this->post_id = $postId;
$this->parent_id = empty($comment->id) ? 0 : ($comment->parent_id ? $comment->parent_id : $comment->id);
$this->target_id = empty($comment->id) ? 0 : $comment->id;
$this->content = ($time > 0 && ! empty($comment->user)) ? '@'.$comment->user->name.':' : '';
$this->comment_composing_box_id = 'comment-composing-box-'.Str::random(10);
$this->preview_box_id = 'preview-box'.Str::random(10);
}
public function submit(): void
{
if ($this->check()) {
$validatedData = $this->validate();
$data = [
'content' => $validatedData['content'],
'user_id' => Auth::user()->id,
'parent_id' => $this->parent_id,
'post_id' => $this->post_id,
'target_id' => $this->target_id,
];
CommentModel::create($data);
$this->reset('content');
$this->emitTo('show-comment', 'create', $this->post_id);
session()->flash('message', '添加评论成功!');
}
}
public function userCommentLimit(MessageBag &$messageBag): void
{
$time = Cache::get(user_comment_limit_key()) ?? 0;
$limit_day_time = config('cache.user_comment_limit.day_time', 10);
if ($limit_day_time < $time) {
$messageBag->add('content', Str::replaceFirst('?', $limit_day_time, '用户每天最多只能回复 ? 评论'));
} else {
Cache::put(user_comment_limit_key(), $time + 1, Carbon::today()->addDay());
}
}
/**
* @param MessageBag $messageBag
*/
public function mustLogin(MessageBag &$messageBag): void
{
Auth::guest() && $messageBag->add('content', '用户需要登陆!');
}
/**
* @return bool
*/
public function check(): bool
{
$messageBag = $this->getErrorBag();
$this->userCommentLimit($messageBag);
$this->mustLogin($messageBag);
return $messageBag->count() === 0;
}
/**
* @return View
*/
public function render(): View
{
return view('livewire.add-comment');
}
}
ShowComment
<?php
namespace App\Http\Livewire;
use App\Models\PostModel;
use App\Repositories\BlogRepository;
use Illuminate\Support\Collection;
use Illuminate\View\View;
use Livewire\Component;
class ShowComment extends Component
{
/**
* @var int
*/
public $postId;
/**
* @var Collection
*/
public $comments;
/**
* @var int
*/
public $comments_count = 0;
/**
* @var array
*/
protected $listeners = ['create' => 'getCommens'];
/**
* @param $postIds
*/
public function mount(PostModel $post): void
{
$this->postId = $post->id;
$this->comments = $post->comments;
$this->comments_count = $post->comments->count() ?? 0;
}
/**
* $params.
*/
public function getCommens(int $postId): void
{
$post = BlogRepository::getPostById($postId);
$this->comments = $post->comments;
$this->comments_count = $post->comments->count() ?? 0;
}
/**
* @return View
*/
public function render(): View
{
return view('livewire.show-comment');
}
}
- 分析
里面比较重要的是emitTo
这个的意思,就是你这个组件处理完成了需要通知到谁,比如通知ShowComment
, 就是$this->emitTo('show-comment', 'create', $this->post_id)
;组件名称可以通过打印ShowComment::getName()
获得。 我遇到的坑
- 评论我是要循环嵌套的。如果每个
show-comment.blade.php
去再嵌套自己,emitTo
就会通知很多个ShowComment
,我暂时没看到 组件可以根据名字+id
去通知同步的。后面我用的include
嵌套循环模版。有兴趣的大家可以看下我代码。
- 评论我是要循环嵌套的。如果每个
- AddComment组件 我是要去验证用户是否登陆的,无法通过中间件实现。我后面是在组件方法里面去验证的。如果大家有好的办法也可以告诉我。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。