You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Livewire实现关注/取关按钮点击后无刷新切换状态持久化

Livewire无刷新关注按钮实现方案

Livewire原生支持你需要的无刷新交互效果,现有代码仅缺少操作完成后的状态同步逻辑,补全后即可实现点击切换按钮、状态持久化、反向切换正常运行的需求,不需要编写额外前端JS代码。


第一步:完善FollowButton组件后端逻辑

原有代码执行关注/取消关注数据库操作后,没有同步更新组件内的$isFollowed公共属性,因此前端不会触发按钮切换,补全后的组件代码如下:

class FollowButton extends Component
{
    public $postAuthorId;
    public $authorName;
    public $isFollowed;
    public Post $post;

    public function mount()
    {
        $this->postAuthorId = $this->post->author->id;
        $this->authorName = $this->post->author->name;
        $this->isFollowed = (bool) $this->post->author->followedBy(auth()->user());
    }

    public function follow()
    {
        // 拦截重复关注请求
        if ($this->isFollowed) {
            return;
        }
        // 拦截关注自己的异常请求
        if ($this->postAuthorId == auth()->id()) {
            session()->flash('error', '你不能关注自己');
            return;
        }

        Follow::create([
            'user_id' => $this->postAuthorId,
            'follower_id' => auth()->id()
        ]);

        // 核心:操作完成后同步更新组件状态,前端会自动重渲染按钮
        $this->isFollowed = true;
        session()->flash('success', '已关注' . $this->authorName);
    }

    public function unfollow()
    {
        // 拦截未关注状态下的取消请求
        if (!$this->isFollowed) {
            return;
        }

        // 删除当前用户与作者的关联关注记录
        Follow::where('user_id', $this->postAuthorId)
            ->where('follower_id', auth()->id())
            ->delete();

        // 核心:同步更新状态,前端自动切换为关注按钮
        $this->isFollowed = false;
        session()->flash('success', '已取消关注' . $this->authorName);
    }

    public function render()
    {
        return view('livewire.follow-button');
    }
}

Livewire每次调用组件方法后会自动重新渲染模板,只要更新了公共属性$isFollowed,前端按钮就会自动切换,所有操作直接写入数据库,刷新页面后状态不会丢失。


第二步:优化前端模板(可选,提升交互体验)

可以利用Livewire自带的wire:loading指令加加载状态,避免用户重复点击,修改follow-button.blade.php代码如下:

<div>
    @if(!$isFollowed)
        <button wire:click="follow" wire:loading.attr="disabled" class="btn btn-default">
            <span wire:loading.remove wire:target="follow">关注</span>
            <span wire:loading wire:target="follow">处理中...</span>
        </button>
    @else
        <button wire:click="unfollow" wire:loading.attr="disabled" class="btn btn-default">
            <span wire:loading.remove wire:target="unfollow">取消关注</span>
            <span wire:loading wire:target="unfollow">处理中...</span>
        </button>
    @endif

    {{-- 不需要提示消息可以删除下面的代码 --}}
    @if(session()->has('success'))
        <div class="text-success mt-1">{{ session('success') }}</div>
    @endif
    @if(session()->has('error'))
        <div class="text-danger mt-1">{{ session('error') }}</div>
    @endif
</div>

第三步:调整组件调用方式(适配多按钮场景)

单篇文章页原有调用方式可以直接使用,如果是文章列表页有多个关注按钮,需要给每个组件加唯一key避免状态串扰:

{{-- 列表页推荐写法 --}}
@livewire('follow-button', ['post' => $post], key('follow-button-'.$post->id))

注意事项

  • 所有关注/取消关注操作直接写入数据库,页面刷新后状态不会丢失,天然满足持久化要求
  • 正反切换逻辑可正常运行:每次操作完成后$isFollowed属性同步更新,Livewire自动重渲染对应按钮,无需手动刷新页面
  • 全程不需要编写额外JavaScript代码,Livewire底层自动完成前后端异步通信
  • 重复操作拦截逻辑可以避免异常请求产生脏数据

内容的提问来源于stack exchange,提问作者Drenyl

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 06:54:22