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

Laravel9+Vue3+FullCalendar5:数据库事件读写及Axios请求故障求助

Laravel 9 + Vue 3 + FullCalendar v5 数据交互故障

我在Laravel 9项目中用Vue 3组件集成了FullCalendar v5,身份认证用Breeze,页面渲染用Inertia。目前Calendar/Pages/Index.vue能正常显示日历,也能通过示例模态框更新日历上的事件,但无法通过模态框把事件存入数据库,也无法从数据库表中拉取事件显示在日历上。我尝试用axios获取JSON数据,避免使用Ajax。

控制器代码(生成JSON)

public function showEvents(Request $request) {
    $event = Event::get(['title','acronym','city','venue','value','start','end']);
    return response()->json(["events" => $event]);
}

返回的JSON数据

{"events":[{"title":"Test","acronym":"TST","city":"Denver","venue":"Big Venue","value":"$0","start":"2022-10-25 00:00:00","end":"2022-10-28 00:00:00"}]}

Calendar/Index.vue 代码

<template>
    <head title="Dashboard" />
    <BreezeAuthenticatedLayout>
        <template #header>
            <h2 class="font-semibold text-xl text-gray-800 leading-tight">
                Resource Calendar Timeline
            </h2>
        </template>
        <div class="py-12">
            <div class="max-w-10xl mx-auto sm:px-6 lg:px-8">
                <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
                    <div class="p-12 bg-white border-b border-gray-200">
<!--start calendar-->
  <div class='demo-app'>
    <div class='demo-app-main'>
      <FullCalendar
        class='demo-app-calendar'
        :events="calendarEvents"
        :options='calendarOptions'>
        <template v-slot:eventContent='arg'>
          <b>{{ arg.timeText }}</b>
          <i>{{ arg.event.title }}</i>
        </template>
      </FullCalendar>
    </div>
  </div>
<!--end calendar-->
                    </div>
                </div>
            </div>
        </div>
    </BreezeAuthenticatedLayout>
</template>
<!--start calendar-->
<script setup lang='ts'>
import BreezeAuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import { head, Link } from '@inertiajs/inertia-vue3';
import '@fullcalendar/core/vdom'; // solves problem with Vite
import { defineComponent } from 'vue';
import FullCalendar, { CalendarOptions, EventApi, DateSelectArg, EventClickArg } from '@fullcalendar/vue3';
import dayGridPlugin from '@fullcalendar/daygrid';
import timeGridPlugin from '@fullcalendar/timegrid';
import listPlugin from '@fullcalendar/list';
import interactionPlugin from '@fullcalendar/interaction';
import axios from 'axios';
</script>
<script lang='ts'>
const Demo = defineComponent({
  components: {
    FullCalendar,
  },
  data() {
    return {
    // 尝试从数据库JSON拉取事件 -->
eventSources: [{
    url: 'https://l9-v3-breeze-crud.ddev.site/show-events', // 使用`url`属性
    color: 'yellow',    // 自定义样式
    textColor: 'black'  // 自定义样式
  }],
calendarEvents: [{
        events(title, start, end, callback) {
          axios.get('https://l9-v3-breeze-crud.ddev.site/show-events').then(res => {
              callback(res.data.events)
            })
          },
          failure: function() {
          alert('拉取事件时出错!');
          },
          color: 'red',
          textColor: 'white',
        }],
        // 结束数据库事件拉取 -->
      calendarOptions: {
        plugins: [
          dayGridPlugin,
          timeGridPlugin,
          listPlugin,
          interactionPlugin // 处理日期点击需要
        ],

        headerToolbar: {
          left: 'promptResource prev,next today',
          center: 'title',
          right: 'dayGridMonth,timeGridWeek,timeGridDay,listMonth'
        },
        
      },
      initialView: 'dayGridMonth',
      events: this.getEvents,
      editable: true,
        selectable: true,
        selectMirror: true,
        dayMaxEvents: true,
        weekends: true,
        select: this.handleDateSelect,
        eventClick: this.handleEventClick,
        eventsSet: this.handleEvents
      } as CalendarOptions,
      currentEvents: [] as EventApi[],
    }
  },
  methods: {
  getEvents(info, successCallback, failureCallback) {
  events(start, end, timezone, callback) {
                    axios.get('http://localhost:8000/show-events').then(res => {
                        callback(res.data.eventList)
                    })
              })
      },
    handleWeekendsToggle() {
      this.calendarOptions.weekends = !this.calendarOptions.weekends // 更新属性
    },
    handleDateSelect(selectInfo: DateSelectArg) {
      let title = prompt('请输入事件标题')
      let calendarApi = selectInfo.view.calendar
      calendarApi.unselect() // 清除日期选择
      if (title) {
        calendarApi.addEvent({
          id: createEventId(),
          title,
          start: selectInfo.startStr,
          end: selectInfo.endStr,
          allDay: selectInfo.allDay
        })
      }
    },
    handleEventClick(clickInfo: EventClickArg) {
      if (confirm(`确定要删除事件'${clickInfo.event.title}'吗?`)) {
        clickInfo.event.remove()
      }
    },
    handleEvents(events: EventApi[]) {
      this.currentEvents = events
    },
  }
})
export default Demo
</script>
<style lang='css'>
h2 {
  margin: 0;
  font-size: 16px;
}
ul {
  margin: 0;
  padding: 0 0 0 1.5em;
}
li {
  margin: 1.5em 0;
  padding: 0;
}
b { /* 用于事件日期/时间 */
  margin-right: 3px;
}
.demo-app {
  display: flex;
  min-height: 100%;
  font-family: Arial, Helvetica Neue, Helvetica, sans-serif;
  font-size: 14px;
}
.demo-app-sidebar {
  width: 300px;
  line-height: 1.5;
  background: #eaf9ff;
  border-right: 1px solid #d3e2e8;
}
.demo-app-sidebar-section {
  padding: 2em;
}
.demo-app-main {
  flex-grow: 1;
  padding: 3em;
}
.fc { /* 日历根元素 */
  max-width: 1200px;
  margin: 0 auto;
}
.fc-day-today
{
background-color: var(--fc-today-bg-color, rgba(255, 220, 40, 0.15));
}
.fc-day-sat, .fc-day-sun
{
background-color: var(--fc-today-bg-color, rgba(255, 100, 40, 0.15));
}
</style>

当前遇到的问题

  • 拉取到空的events数组
  • 调用axios.get时出现500错误,提示:Module source URI is not allowed in this document: "http://[::1]:5173/resources/js/Pages/Calendar/Index.vue"
  • 无法加载calendarEvents配置项:
calendarEvents: [{
        events(title, start, end, callback) {
          axios.get('https://l9-v3-breeze-crud.ddev.site/show-events').then(res => {
              callback(res.data.events)
            })
          },
          failure: function() {
          alert('there was an error while fetching events!');
          },
          color: 'red',
          textColor: 'white',
        }],

补充信息

我找了很多在线示例,但没有一个匹配我的项目依赖。作为新手,我不知道怎么整合代码,尤其是FullCalendar官网的Vue3+TypeScript示例里的Calendar/Index.vue结构,还有另一个Laravel+Vue日历示例的app.js。

我的app.js因为Ziggy和Inertia的安装变得复杂,不确定如何构建Vue组件而非Blade模板,代码如下:

import './bootstrap';
import '../css/app.css';

//import { ZiggyVue } from 'ziggy-vue';
//import route from 'ziggy';

import { createApp, h } from 'vue';
import { ZiggyVue } from '../../vendor/tightenco/ziggy/dist/vue.m';
import { createInertiaApp } from '@inertiajs/inertia-vue3';
import { InertiaProgress } from '@inertiajs/progress';
import { resolvePageComponent } from 'laravel-vite-plugin/inertia-helpers';

const appName = window.document.getElementsByTagName('title')[0]?.innerText || 'Laravel';

createInertiaApp({
    title: (title) => `${title} - ${appName}`,
    resolve: (name) => resolvePageComponent(`./Pages/${name}.vue`, import.meta.glob('./Pages/**/*.vue')),
    setup({ el, app, props, plugin }) {
        return createApp({ render: () => h(app, props) })
            .use(plugin)
            .use(ZiggyVue, Ziggy)
            .mount(el);
    },
});

InertiaProgress.init({ color: '#4B5563' });

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 14:25:27