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
相关产品推荐
相关产品推荐

