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

Laravel Livewire组件重渲染后JavaScript数据未刷新问题

Livewire重渲染时FullCalendar数据不同步问题修复

问题根因

出现该问题是两个核心逻辑错误导致的:

  1. 放在@push('scripts')块内的JS代码只会在页面首次加载时执行一次,后续Livewire组件重渲染不会重新运行这部分代码,所以块内写死的@js($events)永远是第一次渲染时的初始旧值,不会随$events更新。
  2. 每次触发contentChanged事件都重新初始化FullCalendar实例,会导致实例重复创建、内存泄漏,也无法正确更新已渲染日历的数据。

修复步骤

1. 修改后端事件派发逻辑

派发浏览器事件时直接把最新的事件数据放到事件载荷里,不要依赖前端模板静态渲染变量:

// 组件类render方法内
$this->dispatchBrowserEvent('contentChanged', [
    'events' => $this->events
]);

2. 重构前端JS逻辑

把日历初始化和数据更新逻辑拆开,只在页面加载完成时初始化一次日历实例,收到更新事件时直接替换日历数据源即可,修改后的模板代码如下:

<div>
    {{ dump($events) }}
    <x-card class="mt-4">
        <div id='calendar'></div>
    </x-card>
    
    @push('scripts')
        <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.js'></script>
        <script src='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/locales/de.js'></script>
        <link href='https://cdn.jsdelivr.net/npm/fullcalendar@5.11.0/main.min.css' rel='stylesheet' />
        
        <script>
            // 存储全局日历实例,避免重复初始化
            let calendar = null;
            // 页面首次加载完成后初始化日历
            document.addEventListener('DOMContentLoaded', () => {
                const calendarEl = document.getElementById('calendar');
                calendar = new FullCalendar.Calendar(calendarEl, {
                    locale: "de",
                    events: [], // 初始空数据,后续动态更新
                    headerToolbar: {
                        left: 'prev,next today',
                        center: 'title',
                        right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                    },
                    loading: function(isLoading) {
                        if (!isLoading) {
                            this.getEvents().forEach(e => {
                                if (e.source === null) e.remove();
                            });
                        }
                    },
                });
                calendar.render();
            });

            // 监听后端数据更新事件
            document.addEventListener('contentChanged', (e) => {
                // 直接从事件载荷获取最新数据,无需依赖@js静态渲染
                const formattedEvents = e.detail.events.map(event => ({
                    ...event,
                    backgroundColor: event.title < 3 ? '#B23220' : (event.title < 11 ? '#C3B031' : '#20B22C'),
                    borderColor: event.title < 3 ? '#B23220' : (event.title < 11 ? '#C3B031' : '#20B22C'),
                }));
                // 替换日历数据源
                calendar.removeAllEvents();
                calendar.addEventSource(formattedEvents);
            });

            // 原有刷新逻辑可保留
            @this.on('refreshCalendar', () => {
                calendar.refetchEvents();
            });
        </script>
    @endpush
</div>

注意事项

不要在@push('scripts')、@vite这类提前加载的脚本块内,通过Blade指令直接绑定Livewire的动态变量。这类块内的代码不会随Livewire重渲染重新执行,绑定的变量永远是首次页面加载的静态值。动态数据必须通过事件载荷传递,或者调用Livewire前端API主动获取。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 06:01:43