Principle:

Listen for ContextMenu to display the menu

The menu component calculates the pop-up position

<template>
  <a-menu
    v-show="visible"
    :style="style"
    class="contextmenu"
    :selected-keys="selectedKeys"
    @click="handleClick"
  >
    <a-menu-item
      v-for="item in contextMenuList"
      :key="item.key"
    >
      <a-icon
        v-if="item.icon"
        :role="role"
        :type="item.icon"
      />
      {{ item.text }}
    </a-menu-item>
  </a-menu>
</template>

<script>
import T from '@/utils/tools'

export default {
  name: 'Contextmenu'.props: {
    // Menu list
    contextMenuList: {
      type: Array.required: true,},// Click on the element identifier (different roles must be set in multiple places)
    role: {
      type: String.default: (() = > {
        return T.uniqueId // Automatically generate uUID to ensure uniqueness
      })()
    }
  },

  data () {
    return {
      left: 0.top: 0.target: null.selectedKeys: [].visible: false,}},computed: {
    style () {
      return {
        left: this.left + 'px'.top: this.top + 'px'
      }
    }
  },

  created () {
    window.addEventListener('mousedown'.e= > this.closeMenu(e))
    window.addEventListener('contextmenu'.e= > this.setPosition(e))
  },

  methods: {
    closeMenu (e) {
      this.visible = false
    },

    setPosition (e) {
      this.left = e.clientX
      this.top = e.clientY
      this.target = e.target
    },

    handleClick ({ key }) {
      this.$emit('select', key, this.target)
      this.visible = false}}}</script>

<style lang="less" scoped>
  .contextmenu {
    position: fixed;
    z-index: 1;
    border: 1px solid #9e9e9e;
    border-radius: 4px;
    box-shadow: 2px 2px 10px #aaa ! important;
  }
</style>

Copy the code