CyberNika/v-contextmenu

V3 版本开发计划

Closed this issue · 11 comments

已发布 https://github.com/heynext/v-contextmenu/blob/main/README.md


v-contextmenu@3.0

最新代码在 main 分支

近期将启动该组件新版的开发,着重修复遗留问题支持新功能,API 会尽可能做到兼容。
有任何关于该组件的想法,欢迎大家留言,我会第一时间记录。

TypeScript

👀 新版本将使用 TypeScript 开发。1️⃣ 现阶段 Vue 已经可以和 TypeScript 进行不错的结合JSX 虽然不算完美,但是完全可用的。2️⃣ Vue 3.0 将使用 TypeScript 编写,同时带来更完善的 TypeScript 支持。3️⃣ TypeScript 被越来越多的开发者接受和使用,嗯,真香👏。

基于 Vue 3.0 的 Composition API,使用 TypeScript 开发新版本。

需求收集

Bugs

  • selecteddisabled 样式冲突 #52
  • contextmenuId 使用时机导致为 undefined #56

Features

  • 支持多事件绑定 #54
  • 更多场景的 autoHide #50
  • 支持自定义 container #44
  • 支持多个实例同时展示 #59

Enhancements

  • placement 相关优化 #51 #47
  • 组件内 contextmenu 事件冲突 #49
  • 兼容低版本浏览器 #48
  • vnode 更新机制 #43
  • 处理 removeRef
  • 更多内置主题

计划

优先解决 bug,如果不麻烦的话会同步至 2.x

  • 需求收集 2019-03-10
  • 启动开发
  • v3.0.0 发布
  • 单元测试 & CI

菜单能支持添加图标吗?

我说我几点建议,因为上一个项目要用右键,也考察过v-contextmenu,觉得api设计不那么的自然,虽然样式上挺好看的,特别是做动态渲染菜单的时候就很难受,最后我自己造了个contextmenu组件,说一下组件的api设计,主要借鉴了vue-context

<template>
  <div @contextmenu="handleContextMenu">我是右键触发区域</div>

 <contextmenu ref="menu1">
  <template v-slot="scope">
    <ul>
      <li @click="handleMenu1(scope)">我是菜单1</li>
      <li @click="handleMenu2(scope)">我是菜单2</li>
    </ul>
  </template>
 </contextmenu>

</template>

<script>
  export default {
    methods: {
      handleContextMenu (event) {
        let menuScopeData = {}
        this.$refs.menu1.open(event, menuScopeData)
      }
    }
  }
</script>

这样设计增加了开发者的极大自由度

  1. 开发者可以决定点击右键的时候是否弹出菜单
  2. 开发者可以传入自定义的数据data,来进行自定义渲染菜单,以及绑定菜单上的事件
  3. 样式自由,当然也可以内置一些组件比如contextmenu-item,contextmenu-subitem等等,也可以使用elementmenu组件

建议,把v-contextmenu放在我的自定义的组件B,因为这个自定义的组件B可以处理所以右键相关的点击事件。主组件A引用组件B,我在A组件中绑定右键。
我的思路是:B组件里面写死ref

<template>
  <v-contextmenu ref="contextmenu">
    <v-contextmenu-item @click="handleClick">菜单1</v-contextmenu-item>
    <v-contextmenu-item @click="handleClick">菜单2</v-contextmenu-item>
    <v-contextmenu-item @click="handleClick">菜单3</v-contextmenu-item>
  </v-contextmenu>
</template>`

在directive.js里面修改为:


/* eslint-disable no-param-reassign */
export default {
  // 之所以用 inserted 而不是 bind,是需要确保 contentmenu mounted 后才进行 addRef 操作
  inserted (el, binding, vnode) {
    const contextmenu = vnode.context.$refs[binding.arg]
    if (!contextmenu || typeof (contextmenu.addRef) !== 'function') {
      const inner = contextmenu.$refs.contextmenu
      inner.addRef({ el, vnode })
      inner.$contextmenuId = el.id || inner._uid // eslint-disable-line no-underscore-dangle
      return
    }
    contextmenu.addRef({ el, vnode })
    contextmenu.$contextmenuId = el.id || contextmenu._uid // eslint-disable-line no-underscore-dangle
  },
}

@kissfu 需要考虑动态菜单、多个实例等情况

@kissfu 需要考虑动态菜单、多个实例等情况

多谢回答。动态菜单我也考虑过。两个问题。1、右键菜单出现的位置需要计算(计算后出现的位置很奇怪),而且我的右键的位置也是不固定的的;2、我需要添加多余的js代码。 其实我的思路是少量的代码,解耦右键菜单(只在一个组件里面处理所以的右键事件)。

啥时候能支持键盘导航,我希望能用方向键导航菜单的交点项

3.0计划什么时候发布?

IE11 报错,😢

适用于 Vue 3.0 的 版本已发布。https://github.com/heynext/v-contextmenu/blob/main/README.md