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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 17:25:15