FullCalendar重复事件问题:重复创建事件的修复咨询
解决FullCalendar+Vue+Bootstrap Modal重复创建事件的问题
问题核心原因
你遇到的重复创建事件问题,本质是保存按钮的点击事件被多次绑定,且Modal关闭后未清理表单残留数据:
- 每次点击日期触发
selectEventFunction时,即便调用了$('#createEvent').off("click"),jQuery的事件解绑逻辑并不彻底,导致多次打开Modal后,保存按钮上堆积了多个点击回调,一次保存操作会触发多次请求; - Modal关闭后表单数据未清空,之前未提交的日期、内容等信息会残留,再次打开Modal时会被错误提交。
修复方案
1. 改用Vue原生事件绑定替代jQuery动态绑定
放弃在selectEventFunction里用jQuery动态绑定点击事件,直接在Modal的保存按钮上用Vue的@click绑定方法,从根源避免事件堆积。
模板修改示例:
<!-- Bootstrap Modal 内的保存按钮 --> <button id="createEvent" @click="saveEvent" class="btn btn-primary">保存事件</button>
2. 重构保存逻辑到独立方法
把原来写在jQuery点击回调里的保存代码,移到Vue的methods中独立的saveEvent方法:
methods: { // 打开Modal时初始化选中日期 selectEventFunction(selectionInfo) { // 将选中的日期填充到表单的开始/结束日期输入框 const selectedDate = selectionInfo.startStr; $('#eventStart').val(selectedDate); $('#eventEnd').val(selectedDate); // 全天事件默认结束日期与开始日期一致 // 打开Modal $('#addEventCalendar').modal('toggle'); }, // 独立的事件保存逻辑 saveEvent() { // 整合客户端名称取值逻辑 const client_name = $('#chose_client').val() || $('#client_name').val(); const job_name = $('#job_name').val(); const start_date = $('#eventStart').val(); const end_date = $('#eventEnd').val(); const template_name = $('#job_template').val(); const job_type = $('#job_type').val(); const job_description = $('#team_description').val(); const duration = $('#jobDuration').val(); const team_name = $('#assigne_team').val(); const client_phone_number = $('#client_phone').val(); const subject_type = $('#subject_type').val(); const client_adress = $('#client_adress').val(); // 统一用axios发起请求(替换原jQuery ajax,保持项目请求风格一致) axios.post('/jobs', { job_name, start_date, end_date, template_name, job_type, job_description, duration, team_name, client_name, client_phone_number, subject_type, client_adress, }) .then(response => { Toastify({ text: response.data.success, className: "info", duration: 3000, position: "right", gravity: "top", close: true, stopOnFocus: true, style: { background: "#695CFE", } }).showToast(); // 保存成功后关闭Modal $('#addEventCalendar').modal('hide'); // 仅刷新日历数据,无需重载整个页面 this.$refs.calendar.getApi().refetchEvents(); }) .catch(error => { Toastify({ text: error.responseJSON.errors.title, className: "info", duration: 3000, position: "right", gravity: "top", close: true, stopOnFocus: true, style: { background: "#801427", } }).showToast(); }); }, // 其他原有方法(如removeEventfromCalendar)保持不变 }
3. 监听Modal关闭事件,清空表单数据
在mounted钩子中添加Modal关闭的监听,确保每次关闭Modal时清空所有表单字段,避免残留数据:
mounted() { // 初始化CSRF令牌 $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); // 监听Modal关闭事件,清空所有表单输入 $('#addEventCalendar').on('hidden.bs.modal', () => { $('#chose_client').val(''); $('#client_name').val(''); $('#job_name').val(''); $('#eventStart').val(''); $('#eventEnd').val(''); $('#job_template').val(''); $('#job_type').val(''); $('#team_description').val(''); $('#jobDuration').val(''); $('#assigne_team').val(''); $('#client_phone').val(''); $('#subject_type').val(''); $('#client_adress').val(''); }); },
4. 优化日历刷新方式
原代码用location.reload()重载整个页面,换成FullCalendar的refetchEvents()方法仅刷新日历数据,提升用户体验。记得给FullCalendar组件添加ref属性:
<FullCalendar ref="calendar" :options="calendarOptions" />
关键优化点总结
- 用Vue原生事件绑定替代jQuery动态绑定,彻底解决事件重复绑定问题;
- Modal关闭时强制清空表单,从根源避免残留数据被错误提交;
- 用FullCalendar官方API刷新数据,替代页面重载,优化交互体验。
内容的提问来源于stack exchange,提问作者Maison012
相关产品推荐
相关产品推荐

