vue+elementUI表格实现自定义右键菜单

组件代码:

<template>
  <div id="contextmenu" class="contextmenu open">
    <ul class="dropdown-menu" style="min-width: 130px;">
      <template v-for="item in menuItems">
        <li
          v-if="typeof item.children !== 'undefined' && item.children.length > 0"
          :key="item.btnId + 'predivider'"
          class="divider no-margin"
        />
        <li
          :key="item.btnId"
          :class="typeof item.children !== 'undefined' && item.children.length > 0 ? 'dropdown-hover' : ''"
        >
          <a
            v-if="typeof item.children !== 'undefined' && item.children.length > 0"
            tabindex="-1"
            class="clearfix"
          >
            <span class="pull-left" @click.self="handleClick(item)">{{ item.name }}</span>
            <i class="dropdown-expand fa fa-angle-right" />
          </a>
          <a
            v-else
            tabindex="-1"
            @click.self="handleClick(item)"
          >
            {{ item.name }}
          </a>
          <ul
            v-if="typeof item.children !== 'undefined' && item.children.length > 0"
            class="dropdown-menu"
            style="min-width: 130px;"
          >
            <template v-for="childItem in item.children">
              <li
                :key="childItem.btnId"
              >
                <a tabindex="-1" @click.self="handleClick(childItem)">{{ childItem.name }}</a>
              </li>
            </template>
          </ul>
        </li>
        <li
          v-if="typeof item.children !== 'undefined' && item.children.length > 0"
          :key="item.btnId + 'afterdivider'"
          class="divider no-margin"
        />
      </template>
    </ul>
  </div>
</template>
<script>
export default {
  name: 'ContextButton',
  props: {
    menuItems: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      currentRow: {}
    }
  },
  methods: {
    hiddenMenu() {
      this.$emit('hidden-menu')
    },
    handleClick(item) {
      this.$emit('click', item, this.currentRow)
    },
    init(row, event) {
      this.currentRow = row
      const menu = document.querySelector('#contextmenu')
      const mouseX = event.clientX
      const mouseY = event.clientY
      const boundsX = window.innerWidth
      const boundsY = window.innerHeight
      const menuHeight = menu.scrollHeight
      const menuWidth = menu.scrollWidth
      let top
      let left
      const scrollTop = (document.documentElement && document.documentElement.scrollTop) ? document.documentElement.scrollTop : document.body.scrollTop
      if (mouseY + menuHeight > boundsY) {
        const topH = mouseY - menuHeight + scrollTop
        const menuTop = mouseY - menuHeight
        if (topH > 0 && menuTop > 0) {
          top = topH
        } else {
          top = mouseY + scrollTop
        }
      } else {
        top = mouseY + scrollTop
      }
      const scrollLeft = (document.documentElement && document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : document.body.scrollLeft
      if ((mouseX + menuWidth > boundsX) && ((mouseX - menuWidth) > 0)) {
        left = mouseX - menuWidth + scrollLeft
      } else {
        left = mouseX + scrollLeft
      }
      const parentOffsetTop = event.currentTarget.parentElement.offsetTop
      const parentOffsetLeft = event.currentTarget.parentElement.offsetLeft
      menu.style.top = top - parentOffsetTop + 'px'
      menu.style.left = left - parentOffsetLeft + 'px'
      document.addEventListener('click', this.hiddenMenu)
    }
  }
}
</script>
<style scoped>
.contextmenu {
  position: absolute;
  z-index: 1000;
}
</style>

组件使用代码:

<el-table
   ...
   @row-contextmenu="handleContextMenu"
>
</el-table>
<ContextButton
   v-if="menuVisible"
   ref="menuContextButton"
   :menu-items="menuItems"
   @hidden-menu="hiddenMenu"
   @click="menuBtnClick"
/>

 

<script>
export default{
  data() {
    return {
      menuVisible: false,
      menuItems: [
        {
          name: '编辑',
          btnId: 'edit'
        },
        {
          name: '删除',
          btnId: 'delete'
        },
      ]
    }
  },
  methods: {
    handleContextMenu() {
      // 右键方法
      this.menuVisible = false
      this.menuVisible = true
      event.preventDefault()
      this.$nextTick(() => {
        (this.$refs.menuContextButton as any).init(row, event)
      })
    },
    menuBtnClick() {
      // 点击菜单项方法
      if (item.btnId === 'edit') {
        this.editFn(row)
      } else if (item.btnId === 'delete') {
        this.deleteFn(row.id)
      }
    }
    hiddenMenu() {
      // 隐藏菜单方法
      this.menuVisible = false
      document.removeEventListener('click', this.hiddenMenu)
    }
    editFn(row) {
      // 编辑方法
    }
    deleteFn(id) {
      // 删除方法
    }
  }
}
</script>

 

 参考:vue + elementUI 表格右键弹出菜单 - 简书 (jianshu.com)

posted @ 2021-05-08 10:51  bud  阅读(2599)  评论(0编辑  收藏  举报