Code Monkey home page Code Monkey logo

vue3-context-menu's Introduction

vue3-context-menu

A context menu component for Vue3

Screenshot

English | 简体中文


Features

  • Simple and easy to use, small size
  • Provide component mode and function mode
  • Provide multiple theme styles for your use
  • Customizable

Documentation

View Documentation

Click here View online Demo

Usage

npm install -save @imengyu/vue3-context-menu

Then import in the main.ts file:

import '@imengyu/vue3-context-menu/lib/vue3-context-menu.css'
import ContextMenu from '@imengyu/vue3-context-menu'

createApp(App).use(ContextMenu)     

Then you can use the ContextMenu in the .vue file:

import ContextMenu from '@imengyu/vue3-context-menu'

onContextMenu(e : MouseEvent) {
  //prevent the browser's default menu
  e.preventDefault();
  //show your menu
  ContextMenu.showContextMenu({
    x: e.x,
    y: e.y,
    items: [
      { 
        label: "A menu item", 
        onClick: () => {
          alert("You click a menu item");
        }
      },
      { 
        label: "A submenu", 
        children: [
          { label: "Item1" },
          { label: "Item2" },
          { label: "Item3" },
        ]
      },
    ]
  }); 
}

Or component:

<context-menu
  v-model:show="show"
  :options="optionsComponent"
>
  <context-menu-item label="Simple item" @click="onMenuClick(1)" />
  <context-menu-sperator /><!--use this to add sperator-->
  <context-menu-group label="Menu with child">
    <context-menu-item label="Item1" @click="onMenuClick(2)" />
    <context-menu-item label="Item2" @click="onMenuClick(3)" />
    <context-menu-group label="Child with v-for 50">
      <context-menu-item v-for="index of 50" :key="index" :label="'Item3-'+index" @click="onLoopMenuClick(index)" />
    </context-menu-group>
  </context-menu-group>
</context-menu>
data() {
  return {
    show: false,
    optionsComponent: {
      zIndex: 3,
      minWidth: 230,
      x: 500,
      y: 200
    },
  }
},
methods: {
  onButtonClick(e : MouseEvent) {
    //Show component mode menu
    this.show = true;
    this.options.x = e.x;
    this.options.y = e.y;
  },
}

Development

git clone [email protected]:imengyu/vue3-context-menu.git
cd vue3-context-menu
npm install
npm run dev # Development serve project
npm run build-demo # Build example project
npm run build-lib # Build library project

Built-in themes

theme explain example image
default Default theme example-default-dark.jpg
default dark Default theme with dark example-default-dark.jpg
flat Simple flat theme example-default-dark.jpg
flat dark Simple flat theme with dark example-default-dark.jpg
win10 Win10 like theme example-default-dark.jpg
win10 dark Win10 like theme with dark example-default-dark.jpg
mac Mac like theme example-default-dark.jpg
mac dark Mac like theme with dark example-default-dark.jpg

License

MIT

vue3-context-menu's People

Contributors

cheqianxiao avatar croatialu avatar flipworld avatar imengyu avatar jackbailey avatar kjellmf avatar liumingye avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

vue3-context-menu's Issues

Custom Font

How to set it? If there isn't a way, please make it possible

Prevent menu on mobile

How can I prevent it from appearing on mobile and instead using default menu on that platform?

点击事件无法执行/键盘快捷键失效

版本: 1.2.0 (8a4a41c)

运行环境: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/108.0.0.0 Safari/537.36 Edg/108.0.1462.41

点击事件无法执行
image

alertContextMenuItemClicked('Item2') 无法执行 alertContextMenuItemClicked('Item3') 可以执行

键盘快捷键失效
command+r 是浏览器自带的刷新页面的快捷键, 在未打开右键菜单(vue3-context-menu)前可以使用, 打开后就无法使用了, 其他快捷键同理, 是不是组件有地方截获了键盘输入

Closing the context menu by clicking <div class='outside'>

Right now there is no <div class='outside'> element in this library at all and the left mouse button clicks on the elements that are in the background. I need the mouse click to be stopped with a <div class='outside'> element and event.stopPropagation(). After that the context menu and <div class='outside'> should be closed.
We can move this function to MenuOptions.

Can't close using .closeMenu()

let menu = this.$contextmenu({
            x: this.pageX, y: this.pageY, items: items,
        }); // works

menu.closeMenu(); // doesn't work

The error message: "closeMenu is not a function" appears.

Issue with using transform

I had issue settings this up with my GSAP animation library. Once i removed the animation, i got this working very well.

Later on i added a transform: scale(0.95) via javascript and my menu would no longer show. No errors were logged.

So i'm thinking using transform is causing problems. GSAP uses transform as well. But even simple one line doesn't work.

How can i make this work? Can you please confirm for me.

P.s Thanks for the hard work creating this. It's awesome!

Context menu nested below another menu

We have a context menu for the whole page, but we also need a separate menu if the user right-clicks on specific elements on the screen. It doesn't seem like it's working when I add both menus to the divs.

<div v-contextmenu="{ name: 'context-menu-main' }"
<div>Stuff here</div>
<div v-contextmenu="{ name: 'context-menu-lookup'}">Right click here!</div>
</div>

Vue3-context-menu + modal

When used this plugin in vue + the modals of bootsrap not work:

steps to reproduce.

one context menu with one option to open the modal. the function to open the modal is: $("#btnUploadFile").click();
this button is a hidden button that launch the boostrap modal.

the first time work. but after close the modal the context menu not open in next clicks. the method onContextMenu is fired but not show the menu.

caught ReferenceError: Cannot access 'Ut' before initialization

开发环境能正常使用,打包部署后出现:
caught ReferenceError: Cannot access 'Ut' before initialization
at @imengyu-1690772235121.js:1:712
at @imengyu-1690772235121.js:1:717
at @imengyu-1690772235121.js:2:36098
(anonymous) @ @imengyu-1690772235121.js:1
(anonymous) @ @imengyu-1690772235121.js:1
(anonymous) @ @imengyu-1690772235121.js:2

阻止右键事件冒泡后会重复产生菜单应如何处理

您好。因为我子组件和父组件都有右键菜单的需求,所以我阻止了子组件的事件冒泡,但是新带来的问题则是子组件会重复产生新的菜单,如下图,请问这种问题应该要如何处理呢?
20220116_154232

父组件:

<!-- 父组件 -->
<template>
  <div class="box" @contextmenu.prevent="contextmenuHandler">
    <Son />
  </div>
</template>

<script>
import Son from "./Son.vue"

export default {
  name: "Test",
  components: { Son },
  methods: {
    contextmenuHandler(e) {
      console.log("父组件右键....");
      this.$contextmenu({
        x: e.x,
        y: e.y,
        items: [
          {
            label: "父组件菜单",
            onClick: () => {
              alert("父组件菜单点击...");
            }
          }
        ]
      });
    }
  }
}
</script>
<style scoped>
.box {
  margin: 43px;
  border: 1px dashed #000;
  width: 600px;
  height: 400px;
}
</style>

子组件

<!-- 子组件 -->
<template>
  <div class="son" @contextmenu.prevent.stop="contextmenuHandler">子组件</div>
</template>
<script>

export default {
  name: "Son",
  methods: {
    contextmenuHandler(e) {
      console.log("子组件右键....");
      this.$contextmenu({
        x: e.x,
        y: e.y,
        items: [
          {
            label: "子组件菜单",
            onClick: () => {
              alert("子组件菜单点击...");
            }
          }
        ]
      });
    }
  }

}
</script>
<style scoped>
.son {
  width: 300px;
  height: 300px;
  background: #f68;
  color: #fff;
}
</style>

Vue3 / <script setup>

Could you show, how to use vue3-context-menu in

<script setup>

</script>

I tried the next way, but it don't work:

<script lang="ts" setup>
import {PropType, getCurrentInstance} from "vue";
import * as DocumentsTypes from '../../types/common/shared/documents'


const $this = getCurrentInstance()


const props = defineProps({
	data: {
		type: Object as PropType<DocumentsTypes.Sections.Item.Type>,
		required: true,
	},
})


const onContextMenu = (e: MouseEvent) => {
	e.preventDefault()

	console.log('$this', $this)

	// @ts-ignore
	$this.$contextmenu({
		x: e.x,
		y: e.y,
		items: [
			{
				label: "A menu item",
				onClick: () => {
					alert("You click a menu item");
				}
			},
			{
				label: "A submenu",
				children: [
					{ label: "Item1" },
					{ label: "Item2" },
					{ label: "Item3" },
				]
			},
		]
	})
}

</script>



<template>
	<router-link
			:to="'/documents/list/'+data._id"
			@contextmenu="onContextMenu($event)"
	>{{ data.name }}</router-link>
</template>

the error is:
$this.$contextmenu is not a function

[BUG][1.3.1] - Undeclared component

VNodeRender

[Vue warn]: Failed to resolve component: VNodeRender
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement. 
  at <ContextMenuSperator key=0 > 
  at <ContextSubMenu class="mx-menu-host" items=undefined adjustPosition=undefined  ... > 
  at <ContextMenu options=Ref< 
  

Probably because of:

c50455f

I want to donate ❤

The kind of issue we'd like to get more often !

I've search a little but couldn't find any link to donate.
You've done a great job that saves lots of time, I think it's fair to reward you with a bit of money :)

Best regards !

Durss

在全屏对话框上激活contextmenu后无法取消

你好,我在页面上打开一个全屏对话框后,用绑定到对话框上元素的事件方法激活了contextmenu,但是点击contextmenu之外的区域,contextmenu不会消失。而在页面上是正常的,点击区域外contextmenu就取消显示了。

如果右键菜单分割线上一级不固定,是否能支持top进行分割

当前需求会分多个右键操作逻辑。上面部分是按照当前状态变化,中间部分固定的,现在希望分割线能划出;
如:
当前有禁用状态时,右键菜单顺序为,edit-分割线-,delete等操作;如果非禁用下,可能分割线变为edit,disable-分割线-,delete等操作。能确定是delete上一个是分割线。并且是动态变化,有多种逻辑处理。

菜单位置异常,bug较为严重

我尝试去在element tree组件上鼠标右键显示菜单,但是会造成如下结果,错误
image

不清楚这里为什么是max-height:69px固定了
image

另外,不知道为什么会显示轮播箭头,我并不需要它,我只能在全局css中设置它为display:none
image

image

我尝试在配置里对y的值进行修改,但是会存在未知的bug
image
image

vue版本:3.2.45
@imengyu/vue3-context-menu版本: 1.1.3

最后感谢开发者的贡献

Placement issue.

I'm having a problem placing this menu. I get my event x and y position, and place it in the function. But the further i right click down, the further the menu goes up off the screen. I have to give the y a negative position for it to work. there are some other issues also.

document.addEventListener('contextmenu', (e)=>{ console.log('test') this.$contextmenu({ x:e.x, y:e.y, items:[ { label:'hello world' } ] }); })

Use js on menu

How to remove a menu option if a js condition is true?

Max Y position.

Hello. Thanks for the great work. For me, the context menu does not go below 928. I manually set the y position to 1159, but the menu does not go down there. Stops at 928. Help solve this problem. Thank you

function onContextMenu(e) {
  e.preventDefault();
  const scaledPosition = ContextMenu.transformMenuPosition(e.target as HTMLElement, e.offsetX, e.offsetY);
  menuData.x = scaledPosition.x;
  menuData.y = 1159;
  ContextMenu.showContextMenu(menuData);
}

Error when trying to use vuetify components inside the menu

Example:

<template>
  <context-menu>
    <template
      #itemRender="{
        disabled,
        label,
        icon,
        showRightArrow,
        onClick,
        onMouseEnter,
        keyBoardFocusMenu,
        showSubMenu,
      }"
    >
      <div
        :class="[
          'mx-context-menu-item',
          disabled ? ' disabled' : '',
          keyBoardFocusMenu ? 'keyboard-focus' : '',
          showSubMenu ? 'open' : '',
        ]"
        @click="onClick"
        @mouseenter="onMouseEnter"
      >
        <v-img
          src="https://imengyu.top/assets/images/test/icon.png"
          style="width: 20px; height: 20px"
        />
        <i
          v-if="icon"
          :class="`${icon} v-icon notranslate v-theme--light v-icon--size-small d-flex mr-4`"
        />

        <div
          v-else
          class="v-icon notranslate v-theme--light v-icon--size-small d-flex mr-4"
        />

        <span v-if="label" class="flex-grow-1">{{ label }}</span>

        <span v-if="showRightArrow" class="right-arraw">
          <i
            :class="`fas fa-caret-right v-icon notranslate v-theme--light v-icon--size-small d-flex ml-4`"
          />
        </span>
      </div>
    </template>

    <slot />
  </context-menu>
</template>

<script setup lang="ts"></script>
defaults.ts:28 Uncaught (in promise) Error: [Vuetify] Could not find defaults instance
    at injectDefaults (defaults.ts:28:24)
    at setup (defineComponent.tsx:109:24)
    at callWithErrorHandling (chunk-CVEDGHOZ.js:186:18)
    at setupStatefulComponent (chunk-CVEDGHOZ.js:6203:25)
    at setupComponent (chunk-CVEDGHOZ.js:6164:36)
    at mountComponent (chunk-CVEDGHOZ.js:4801:7)
    at processComponent (chunk-CVEDGHOZ.js:4767:9)
    at patch (chunk-CVEDGHOZ.js:4240:11)
    at mountChildren (chunk-CVEDGHOZ.js:4484:7)
    at mountElement (chunk-CVEDGHOZ.js:4391:7)

Export component ?

How to import components directly?

import {
  ContextMenu,
  ContextMenuItem,
  ContextMenuGroup,
} from '@imengyu/vue3-context-menu';

Unfortunately, all that was undefined. (.d.ts tell me it's ok)


感谢贡献🙏🏻🙏🏻
怎样能直接import到ContextMenu等组件呢?因为我用JSX不希望使用全局的.use
类型提示告诉我可以像上述那么做,但实际得到的结果是undefined,似乎并没有导出组件源码。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.