FullCalendar日历组件集成系列7——实现右键菜单

实现右键菜单

功能需求

在前面的基础上,我们进一步增加业务功能,使其用起来更方便。
具体来说,就是为事件(对应任务)增加右键菜单,能便捷的进行操作,如复制任务、删除任务、添加工时等。
先翻找官方文档,日历组件并没有预置右键菜单扩展,也没有相关说明,需要自行摸索实现。

实现思路1——使用插槽

使用eventContent插槽,自行用div包起来,然后在div上添加@contextmenu事件,如下所示:

  <div> 
    <FullCalendar :options="calendarOptions" ref="fullCalendar">
      <template #eventContent="arg">
        <div @contextmenu="contextmenu"> {{ arg.event.title }} </div>
      </template>
    </FullCalendar>
  </div>

 contextmenu(e) {
    e.preventDefault()
    console.log(e)
 }

上述方式可以显示事件的名称,但右键菜单的处理无效,浏览器的右键菜单还是会弹出来,推测组件又做了啥内部处理和封装导致的,contextmenu根本不会被调用。

在外侧放了一个div标签挂载了contextmenu做对比验证,发现能正常运行,基本确定是日历组件内部处理导致的。

  <div>
    <div @contextmenu="contextmenu"> 测试 </div>
    <FullCalendar :options="calendarOptions" ref="fullCalendar">
      <template #eventContent="arg">
        <div @contextmenu="contextmenu"> {{ arg.event.title }} </div>
      </template>
    </FullCalendar>
  </div>

因此,此路走不通。
此外,即使右键菜单能生效,该方案还存在一个问题,就是需要自己覆写日历组件的内容展现部分,意味着官方原先一些预置的属性和功能,如是否显示事件的起止时间、颜色和背景的控制等,将失去作用,因此,强烈不建议采用此思路。

实现思路2——使用回调

组件预置了一个事件加载完成后的回调事件,我们可以在这个环节添加一个右键监听,然后阻止浏览器默认右键菜单,并调用自己的右键菜单。

// 事件加载完成
eventDidMount(arg) {
  //添加右键菜单
  arg.el.addEventListener('contextmenu', (e) => {
    //阻止浏览器的默认右键菜单
    e.preventDefault()
    this.showEventContextMenu(e, arg.event.id)
  })
}

调用右键菜单如下:

// 显示事件右键菜单
showEventContextMenu(mouseEvent, eventId) {
  // 保存当前事件标识
  this.contextMenuEventId = eventId
  // 显示右键菜单
  this.$nextTick(() => {
    this.eventContextMenu.left = mouseEvent.clientX - 10
    const menuHeight = this.$refs.eventContextMenu.$el.clientHeight
    const areaHeight = document.documentElement.clientHeight

    if (mouseEvent.clientY + menuHeight > areaHeight) {
      // 当鼠标点击的y坐标加上菜单高度超出区域高度时
      this.eventContextMenu.top = mouseEvent.clientY - menuHeight + 25
    } else {
      this.eventContextMenu.top = mouseEvent.clientY - 25
    }
    // 显示菜单
    this.eventContextMenu.visible = true
  })
}

相应的右键菜单使用element-plus的菜单控件,如下:

<el-menu
      v-show="eventContextMenu.visible"
      ref="eventContextMenu"
      :style="{
        width: '120px',
        left: eventContextMenu.left + 'px',
        top: eventContextMenu.top + 'px',
        position: 'fixed',
        cursor: 'pointer',
        'z-index': 9999
      }"
      popper-append-to-body
      @mouseleave="eventContextMenu.visible = false"
      @select="eventContextMenuSelect"
    >
      <el-menu-item index="addLog">
        <el-icon>
          <CloseBold />
        </el-icon>
        <span>记录用时</span></el-menu-item
      >
      <el-menu-item index="copy">
        <el-icon>
          <CopyDocument />
        </el-icon>
        <span>复制任务</span></el-menu-item
      >
      <el-menu-item index="remove">
        <el-icon>
          <FolderRemove />
        </el-icon>
        <span>删除任务</span></el-menu-item
      >
    </el-menu>

这个过程中需要一些属性来保存和传递数据,如下:

// 当前右键菜单事件标识
contextMenuEventId: '',
// 事件右键菜单属性
eventContextMenu: {
  // 是否可见
  visible: false,
  // 左边距
  left: 0,
  // 上边距
  top: 0
}

效果如下:
image.png

应用系统

名称:遇见
地址:https://meet.popsoft.tech
说明:基于一二三应用开发平台和FullCalendar日历组件实现的面向个人的时间管理、任务管理系统,1分钟注册,完整功能,欢迎使用~

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学海无涯,行者无疆

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值