Skip to content

鼠标右键方案

安装

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

vue3-context-menu 仅支持 Vue3,如果你在使用 Vue2,可以试试下面的库。

如果是 vue2 试试下面

vue-context-menu

menujs

全局导入

js
//main.js
import "@imengyu/vue3-context-menu/lib/vue3-context-menu.css";
import ContextMenu from "@imengyu/vue3-context-menu";

createApp(App).use(ContextMenu).mount("#app");

开始使用

创建核心组件

vue
<template>
  <!--this is Full Customized context-menu-->
  <context-menu :show="show" :options="{ ...options, x, y }">
    <!--itemRender slot can customize the rendering of the entire menu item-->
    <template
      #itemRender="{
        disabled,
        label,
        icon,
        showRightArrow,
        onClick,
        onMouseEnter,
      }"
    >
      <div
        :class="'my-menu-item' + (disabled ? ' disabled' : '')"
        @click="onClick"
        @mouseenter="onMouseEnter"
      >
        <img v-if="icon" :src="icon" style="margin-right: 10px" />
        <div v-else class="icon-place-holder"></div>
        <span>{{ label }}</span>
        <span v-if="showRightArrow" class="right-arraw">>></span>
      </div>
    </template>
    <!--模板结束-->
    <!--举例开始-->
    <div
      :class="'my-menu-item' + (disabled ? ' disabled' : '')"
      @click="onClick"
      @mouseenter="onMouseEnter"
    >
      <img v-if="icon" :src="icon" />
      <div v-else class="icon-place-holder"></div>
      <span>{{ label }}</span>
      <span v-if="showRightArrow" class="right-arraw">>></span>
    </div>
    <!--举例-->
    <slot />
  </context-menu>
</template>

<script setup>
/* 组件数据 */
const options = ref({
  customClass: "my-menu-box",
  zIndex: 999,
  minWidth: 230,
});
const show = ref(false);
const Props = defineProps({
  x: {
    type: Number,
    required: true,
  },
  y: {
    type: Number,
    required: true,
  },
});

const onShow = () => {
  show.value = true;
};
const onHide = () => {
  show.value = false;
};
/* 自定义 */
const onClick = () => {
  console.log("hahaha");
};
const label = ref("第一个测试中");
const icon = ref("https://file.jsopy.com/DemoAll/Vue3Cms/guest.png");
const showRightArrow = ref(false);
const disabled = ref(false);
const onMouseEnter = () => {
  console.log("鼠标移入");
};
/* 自定义结束 */
defineExpose({
  onShow,
  onHide,
});
</script>

<style>
.my-menu-box {
  border-radius: 0 !important;
  box-shadow: none !important;
  border: 1px solid #585858 !important;
  background-color: #fff !important;
  padding: 0 !important;
}
.my-menu-item {
  padding: 2px 10px;
  display: flex;
  flex-direction: row;
  justify-content: flex-start;
  align-items: center;
  user-select: none;
}
.my-menu-item:hover {
  background-color: rgb(223, 223, 223);
}
.my-menu-item .icon-place-holder {
  width: 20px;
  height: 20px;
}
.my-menu-item img {
  width: 20px;
  height: 20px;
  margin-right: 20px;
}
.my-menu-item span {
  font-size: 15px;
  color: #000;
  white-space: nowrap;
}
.my-menu-item .right-arraw {
  font-size: 20px;
  color: #f05;
}
.my-menu-sperator {
  border-bottom: 1px dashed #f00;
}
</style>

调用

  • 我这里随便写了个组件调用,你可以根据自己需求来写.绑定到 tagsview
vue
<!--调用元素开始-->
<template>
  <div @contextmenu="onContextMenu($event)">右键点击我</div>
  <!--调用元素结束-->
  <!--鼠标右键开始-->
  <ContextMenu :x="x" :y="y" ref="contextmenu">
    <context-menu-item
      label="Simple item"
      @click="alertContextMenuItemClicked('Item1')"
    />
    <context-menu-item
      label="Item with a icon"
      icon="https://file.jsopy.com/DemoAll/Vue3Cms/guest.png"
      @click="alertContextMenuItemClicked('Item2')"
    />
    <context-menu-group label="Menu with child">
      <context-menu-item
        label="Item1"
        @click="alertContextMenuItemClicked('Item1')"
      />
      <context-menu-item
        label="Item1"
        @click="alertContextMenuItemClicked('Item1')"
      />
    </context-menu-group>
    <div class="my-menu-sperator"></div>
    <context-menu-group label="Menu with child child child">
      <context-menu-item
        label="Item1"
        @click="alertContextMenuItemClicked('Item1')"
      />
      <context-menu-item
        label="Item2"
        @click="alertContextMenuItemClicked('Item2')"
      />
      <context-menu-group label="Child with v-for 50">
        <context-menu-item
          v-for="index of 50"
          :key="index"
          :label="'Item3-' + index"
          @click="alertContextMenuItemClicked('Item3' + index)"
        />
      </context-menu-group>
      <div class="my-menu-sperator"></div>
      <context-menu-group label="Childs">
        <context-menu-item
          label="Item1-1"
          @click="alertContextMenuItemClicked('Item1-1')"
        />
        <context-menu-item
          label="Item1-2"
          @click="alertContextMenuItemClicked('Item1-2')"
        />
        <div class="my-menu-sperator"></div>
        <context-menu-group label="Childs">
          <context-menu-item
            label="Item2-1"
            @click="alertContextMenuItemClicked('Item2-1')"
          />
          <context-menu-item
            label="Item2-2"
            @click="alertContextMenuItemClicked('Item2-2')"
          />
        </context-menu-group>
      </context-menu-group>
    </context-menu-group>
  </ContextMenu>
  <!--鼠标右键结束-->
</template>
<script setup>
/* 右键菜单 */
const contextmenu = ref(null);
const x = ref(500);
const y = ref(200);

const onContextMenu = (e) => {
  e.preventDefault();
  /* 获取鼠标点击位置 */
  x.value = e.x;
  y.value = e.y;
  /* 显示 */
  contextmenu.value.onShow();
};
const alertContextMenuItemClicked = (name) => {
  console.log(name);
  contextmenu.value.onHide();
};
/* 右键菜单结束 */
</script>