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

升级Livewire至v3后Fullcalendar报错:无法读取events属性

Livewire 3.0 结合 FullCalendar 报错:Cannot read properties of undefined (reading 'events')

升级Livewire从"livewire/livewire": "^2.6"到"livewire/livewire": "^3.0"后,控制台出现以下错误:

"Cannot read properties of undefined (reading 'events')"

错误栈信息:

calendar:1423 Uncaught TypeError: Cannot read properties of undefined (reading 'events')
    at HTMLDocument.<anonymous> (calendar:1423:70)
    at dispatch (livewire.js?id=2f6e5d4d:316:8)
    at Object.start2 [as start] (livewire.js?id=2f6e5d4d:6693:5)
    at HTMLDocument.<anonymous> (livewire.js?id=2f6e5d4d:7695:17)

我的Livewire组件代码

<?php

namespace App\Livewire;

use Livewire\Component;
use App\Models\Workflow\Orders;
use Illuminate\Support\Facades\DB;

class Calendar extends Component
{
    public $events = '';

    public function render()
    {
        $events =Orders::select('id', 'code AS title', 'validity_date AS start', 'statu AS color', DB::raw("1 as url"))
                            ->get()
                            ->map(function ($order) {
                                $order->color = str_replace('2', "#ffc107", $order->color);
                                $order->color = str_replace('3', "#28a745", $order->color);
                                
                                $order->url = route('orders.show', $order->id);
                                return $order;
                            });
        $this->events = json_encode($events);
        return view('livewire.calendar');
    }
}

视图代码

<div>
    <div>
        <div id="calendar-container" wire:ignore>
            <div id="calendar"></div>
        </div>
    </div>
</div>

@section('js')
    <script src='https://cdn.jsdelivr.net/npm/fullcalendar@6.1.9/index.global.min.js'></script>
    <script>
        document.addEventListener('livewire:init', function () {
            
            var data =   @this.events;
            const Calendar = FullCalendar.Calendar;
            const calendarEl = document.getElementById('calendar');
            const calendar = new Calendar(calendarEl, 
            {
                events: JSON.parse(data),
                eventColor: '#378006',
                height: 800,
                themeSystem: 'bootstrap',
                headerToolbar: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'dayGridMonth,timeGridWeek,timeGridDay,listWeek'
                },
                locale: '{{ config('app.locale') }}',
            });
            
            calendar.render();
        });
    </script>
    <link href='https://cdn.jsdelivr.net/npm/bootstrap@4.5.0/dist/css/bootstrap.css' rel='stylesheet'>
    <link href='https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.13.1/css/all.css' rel='stylesheet'>
@stop

已尝试操作

  • 按Livewire迁移文档要求,将livewire:load事件替换为livewire:init,问题未解决。

调试思路与解决方案

调试思路

  1. 确认@this初始化时机:Livewire 3中livewire:init是最早的初始化事件,此时组件实例可能未完全挂载,导致无法读取events属性。
  2. 验证$events数据有效性:检查json_encode($events)生成的内容是否为合法JSON,避免JSON.parse解析失败。
  3. 排查组件数据传递逻辑:确认组件的$events属性是否在前端渲染时已完成赋值。

解决方案

方案1:替换为livewire:initialized事件

livewire:initialized事件触发时机晚于livewire:init,此时组件实例已完全挂载:

document.addEventListener('livewire:initialized', function () {
    var data = @this.events;
    const Calendar = FullCalendar.Calendar;
    const calendarEl = document.getElementById('calendar');
    const calendar = new Calendar(calendarEl, 
    {
        events: JSON.parse(data),
        // 剩余配置不变
    });
    
    calendar.render();
});

方案2:直接通过Blade传递数据

取消组件中$events的公共属性赋值,直接将数据传递到视图,绕过Livewire前端实例依赖:

  • 修改Livewire组件:
public function render()
{
    $events = Orders::select('id', 'code AS title', 'validity_date AS start', 'statu AS color')
                        ->get()
                        ->map(function ($order) {
                            $order->color = str_replace('2', "#ffc107", $order->color);
                            $order->color = str_replace('3', "#28a745", $order->color);
                            $order->url = route('orders.show', $order->id);
                            return $order;
                        });
    return view('livewire.calendar', compact('events'));
}
  • 修改视图JS部分:
document.addEventListener('livewire:init', function () {
    // 直接使用Blade变量,无需JSON.parse
    var data = {!! json_encode($events) !!};
    const Calendar = FullCalendar.Calendar;
    const calendarEl = document.getElementById('calendar');
    const calendar = new Calendar(calendarEl, 
    {
        events: data,
        // 剩余配置不变
    });
    
    calendar.render();
});

方案3:通过Livewire事件传递数据

组件挂载完成后主动向前端发送事件,传递日历数据:

  • 修改Livewire组件:
public function mount()
{
    $events = Orders::select('id', 'code AS title', 'validity_date AS start', 'statu AS color')
                        ->get()
                        ->map(function ($order) {
                            $order->color = str_replace('2', "#ffc107", $order->color);
                            $order->color = str_replace('3', "#28a745", $order->color);
                            $order->url = route('orders.show', $order->id);
                            return $order;
                        });
    $this->dispatch('calendarEventsLoaded', events: $events);
}
  • 修改视图JS:
document.addEventListener('livewire:init', function () {
    const Calendar = FullCalendar.Calendar;
    const calendarEl = document.getElementById('calendar');
    const calendar = new Calendar(calendarEl, 
    {
        events: [],
        // 剩余配置不变
    });
    
    calendar.render();

    // 监听组件发送的事件,更新日历数据
    Livewire.on('calendarEventsLoaded', function(data) {
        calendar.removeAllEvents();
        calendar.addEventSource(data.events);
    });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 14:20:55