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

Vue.js中FullCalendar按用户切换显示/隐藏事件的实现求助

在Vue.js中实现FullCalendar的用户事件显示/隐藏

嘿,我来帮你把jQuery的FullCalendar事件过滤逻辑迁移到Vue里!核心思路是利用Vue的响应式数据驱动过滤,替代jQuery的DOM监听方式,这更符合Vue的开发习惯。

步骤1:添加响应式过滤变量

首先在组件的data里新增一个变量,用来存储当前选中的用户ID(默认设为'all'表示显示所有事件):

data() {
  return {
    events: [],
    selectedAccount: 'all', // 新增:当前选中的用户ID,'all'显示全部
    eventRender: (event, element, view) => { // 改成箭头函数,确保this指向组件实例
      return ['all', event.account_id].indexOf(this.selectedAccount) >= 0
    },
    // ... 保留原有config等配置
  }
}

步骤2:添加用户选择控件

在组件模板中添加一个下拉选择器(或按钮组),绑定到selectedAccount,让用户可以切换显示的用户:

<template>
  <div>
    <!-- 用户选择下拉框 -->
    <select v-model="selectedAccount">
      <option value="all">显示所有成员</option>
      <!-- 动态渲染成员选项,需先获取成员列表 -->
      <option v-for="member in members" :key="member.id" :value="member.id">
        {{ member.name }}
      </option>
    </select>

    <!-- FullCalendar组件,添加ref以便操作实例 -->
    <full-calendar 
      ref="calendar"
      :events="events" 
      :config="config"
      :event-render="eventRender"
    ></full-calendar>
  </div>
</template>

注意给FullCalendar组件加上ref="calendar",这样能在代码中获取日历实例,触发重新渲染。

步骤3:监听过滤条件变化,触发日历重渲染

添加watch监听selectedAccount的变化,每当用户切换选择时,调用FullCalendar的rerenderEvents方法重新过滤并渲染事件:

watch: {
  selectedAccount() {
    // 调用日历实例的重渲染方法,不同版本的vue-full-calendar写法可能略有不同
    this.$refs.calendar.$calendar.rerenderEvents();
    // 如果上面的写法无效,试试:this.$refs.calendar.fullCalendar('rerenderEvents')
  }
}

步骤4:完善成员列表(可选)

如果你还没有成员列表数据,可以在getReminders方法中顺便收集所有唯一的用户信息,生成成员列表:

data() {
  return {
    // ... 其他数据
    members: [] // 新增:存储成员列表
  }
},
methods: {
  getReminders: function() {
    var url;
    var accountID=[];
    const memberMap = {}; // 用对象去重,存储唯一成员
    axios.get(route('calendar.reminders'))
      .then((response) => {
        console.log(response.data);
        $(response.data).each((i,data) => {
          // ... 原有生成events的逻辑
          // 收集成员信息(假设接口返回用户名,没有的话用ID代替)
          if (!memberMap[data.accountID]) {
            memberMap[data.accountID] = {
              id: data.accountID,
              name: data.accountName || `成员${data.accountID}`
            };
          }
        });
        // 把对象转成数组存入members
        this.members = Object.values(memberMap);
      });
  },
  // ... 保留原有getRandomColor方法
}

完整修改后的组件示例

整合所有修改后,你的组件代码大概是这样的:

<template>
  <div>
    <select v-model="selectedAccount">
      <option value="all">显示所有成员</option>
      <option v-for="member in members" :key="member.id" :value="member.id">
        {{ member.name }}
      </option>
    </select>

    <full-calendar 
      ref="calendar"
      :events="events" 
      :config="config"
      :event-render="eventRender"
    ></full-calendar>
  </div>
</template>

<script>
import VPopover from 'vue-js-popover';
import FullCalendar from 'vue-full-calendar';
import team from './team'
import axios from 'axios';

Vue.use(VPopover, { tooltip: true});
Vue.use(FullCalendar);

export default {
  data() {
    return {
      events: [],
      members: [],
      selectedAccount: 'all',
      eventRender: (event, element, view) => {
        return ['all', event.account_id].indexOf(this.selectedAccount) >= 0
      },
      config: {
        defaultView: 'month',
        editable: false,
        timeFormat: 'h(:mm) a',
        eventLimit: 4,
        eventTextColor: 'white',
        eventClick: function(event) {
          if (event.url) {
            location.replace(event.url);
            return false;
          }
        }
      }
    }
  },
  components: { team },
  mounted: function() {
    this.getReminders();
  },
  watch: {
    selectedAccount() {
      this.$refs.calendar.$calendar.rerenderEvents();
    }
  },
  methods: {
    getReminders: function() {
      var url;
      var accountID=[];
      const memberMap = {};
      axios.get(route('calendar.reminders'))
        .then((response) => {
          $(response.data).each((i,data) => {
            if(data.subscriber_uid != "") url = 'contacts/list/'+data.list_uid+'/contact/'+data.subscriber_uid;
            else url = null;
            if(typeof accountID[data.accountID] === 'undefined') accountID[data.accountID] = this.getRandomColor();
            this.events.push({
              title : data.reminder_type.name+", "+data.notes,
              start : data.deadline,
              description : data.notes,
              url: url,
              backgroundColor: accountID[data.accountID],
              account_id: data.accountID
            });
            // 收集成员信息
            if (!memberMap[data.accountID]) {
              memberMap[data.accountID] = {
                id: data.accountID,
                name: data.accountName || `成员${data.accountID}`
              };
            }
          });
          this.members = Object.values(memberMap);
        });
    },
    getRandomColor: function() {
      var letters = '0123456789ABCDEF';
      var color = '#';
      for (var i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
      }
      return color;
    }
  }
}
</script>

为什么这么做?

  • 用Vue的响应式变量selectedAccount替代jQuery的DOM值获取,完全遵循Vue的数据驱动思想。
  • 箭头函数确保eventRender里的this指向组件实例,能正确访问过滤变量。
  • 通过watch监听变量变化,主动触发日历重渲染,替代jQuery的DOM事件监听。

这样就能实现和jQuery版本完全一致的效果,而且完全适配Vue的开发模式啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:28:17