组件代码:

<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)

vue+elementUI表格实现自定义右键菜单的更多相关文章

  1. ASP.NET Aries 入门开发教程8:树型列表及自定义右键菜单

    前言: 前面几篇重点都在讲普通列表的相关操作. 本篇主要讲树型列表的操作. 框架在设计时,已经把树型列表和普通列表全面统一了操作,用法几乎是一致的. 下面介绍一些差距化的内容: 1:树型列表绑定: v ...

  2. JavaScript自定义右键菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  3. 自定义右键菜单,禁用浏览器自带的右键菜单[右键菜单实现--Demo]

    许多从事Web开发的会发现有些事,我们需要禁用浏览器本事自带的右键菜单,而实现自定义的右键菜单下面我们也来实现一个自定义的右键菜单 首先来创建JSP页面 <%@ page language=&q ...

  4. JS简单实现自定义右键菜单

    RT,一个简单的例子,仅仅讲述原理 <div id="menu" style="width: 0;height: 0;background: cadetblue;p ...

  5. antd Tree组件中,自定义右键菜单

    最近项目中,有一个需求是自定义antd的Tree组件的右键菜单功能. 直接上代码 class Demo extends Component { state = { rightClickNodeTree ...

  6. AS3.0 自定义右键菜单类

    AS3.0 自定义右键菜单类: /** * 自定义右键菜单类 * 自定义菜单项不得超过15个,每个标题必须至少包含一个可见字符. * 标题字符不能超过100个,并且开头的空白字符会被忽略. * 与任何 ...

  7. js之自定义右键菜单

    <!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. [ActionScript 3.0] 自定义右键菜单

    将自定义右键菜单的一些属性和方法归纳到AddRightMenu.as,通过实例化此类,调用相关方法即可测试! package { import flash.display.Sprite; import ...

  9. 【连载】Bootstrap开发漂亮的前端界面之自定义右键菜单

    连载: 1<教你用Bootstrap开发漂亮的前端界面> 2.<Bootstrap开发漂亮的前端界面之实现原理> 网页中的自定义右键菜单越来越普遍,自定义右键菜单可以增强用户体 ...

  10. 阻止右键菜单(阻止默认事件)&&跟随鼠标移动(大图展示)&&自定义右键菜单

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. Maven初学习

    Maven初学习 摘要:本篇笔记记录了我在初学Maven是认为比较重要的一些知识点. 目录 Maven初学习 1.Maven简介 1.1.项目构建 Ant Maven Gradle 1.2.总结 2. ...

  2. pip19.2.3升级到20.3.3版本升级失败问题

    2021-01-06 macOS版本:11.1 安装pip: sudo easy_install pip   话不多说,直接上问题   一行命令搞定 终端:sudo pip install --upg ...

  3. 【Allwinner】---全志GPIO号 计算

    全志的GPIO号在 sunxi-gpio.h 中定义 sunxi-gpio.h1二.GPIO号定义#define SUNXI_PA_BASE 0#define SUNXI_PB_BASE 32#def ...

  4. 数据预处理时为什么要使用OneHot编码?

    什么是LabelEncoder(整数编码) 整数编码 将一列文本数据转化成数值,即列中的每一个特征都通过一个整数来表示.例如,[red, blue, red, yellow] = [0,2,0,1]. ...

  5. 红客突击队&突击队分队

    红客突击队,于2019年,由队长k龙联合国内多位顶尖高校研究生牵头成立.其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验.团队现有三十多位正式成员及若干预备人员,旨在打造国 ...

  6. yarn使用 以及和npm对比

    yarn是facebook发布的一款取代npm的包管理工具. yarn的特点: 速度超快. Yarn 缓存了每个下载过的包,所以再次使用时无需重复下载. 同时利用并行下载以最大化资源利用率,因此安装速 ...

  7. 合并JSON文件

    下面是一段简单地代码 用来减少工作量合并代码 <!DOCTYPE html> <html lang="en"> <head> <meta ...

  8. 【学习笔记】珂朵莉树(ODT)

    珂朵莉树 \(\tt 0x00\) 起源 起源于 CodeForces 的一题 CF896C,当时出题人提供了这种做法,在随机数据下均摊复杂度比较优秀. 正统名字好像叫颜色段均摊,由于题目也得名于 \ ...

  9. 默认方法:and-默认方法:or

    默认方法:and 既然是条件判断,就会存在与.或.非三种常见的逻辑关系.其中将两个Predicate条件使用"与"逻辑连接起来实现"并且"的效果时,可以使用de ...

  10. React组件渲染触发的条件-归纳总结

    一.React组件何时发生渲染--何时会生成React元素? React组件的渲染发生在两个阶段. 1. 组件挂载. 2. 组件更新. 二.React组件更新的触发条件是什么? 对没有实现should ...