25-Vue 2.x (比如ELEMENT-UI 树形控件)右键菜单组件,菜单内容可以随意自定义
原文:
element-ui 的树形控件本身是不支持右键的,官方文档上推荐把操作按钮展示在对应的项上,但是如果操作项比较多,或者本身就有信息需要展示在项上,再加上这些操作按钮就会比较凌乱。正好公司业务上有这个需求,因此我在网上搜了一圈,找到比较好的解决方式。
整体思路就是:当右键时,调用左键的 node-click
方法,通过 node-click
将获取到的数据储存起来,然后展示右键菜单,获取到数据后,怎么处理就可以自由发挥了。
右键菜单我使用了 vue-context-menu 插件,引入方式可看 README
。
下面是具体代码:
<div id="app">
|
export default {
|
html,
|
以上就是完整代码。
当然还有另外一种思路。el-tree 自带有 node-contextmenu
事件,如果使用了这个事件,原生的右键事件都会被阻止,因此上面方法不能与这个事件一起使用,会造成右键插件无法正常显示。但是 node-contextmenu
事件返回了非常详细的参数:依次为 event、传递给 data
属性的数组中该节点所对应的对象、节点对应的 Node、节点组件本身。由于可以获取到 event,里面带有鼠标右击的坐标,因此完全可以自己写一个右键菜单,而且这个事件的回调参数更为丰富。
补充:上面的示例是把右键出菜单这个功能绑定到了
this.contextMenuTarget = document.querySelector('#el-tree')
这个下面的所有的树节点上,并通过下面的
const tree = document.querySelectorAll('#el-tree [role="treeitem"]')
通过标签选择器,为el-tree下的所有role="treeitem"监听了右键事件,但是如有有需求,不想给树的所有层级都添加右键功能,也就是说是否可以指定层级绑定这个功能呢?
是可以的,上面的逻辑坐下微调,比如只想给业务线这个二级树添加这个功能,那么将上面的标签选择器,选择为儿子一代,而不是在所有的子孙中找符合的元素
async initTreeData() { await getTreeData().then(response => { this.data = response.data; this.handleNodeClick(this.data[0]) //初始化展示的节点 }).catch(error => { console.log(error.response); }); this.$nextTick(() => { // vue-context-menu 需要传入一个触发右键事件的元素,等页面 dom 渲染完毕后才可获取 this.contextMenuTarget = document.querySelector('#el-tree') // 获取所有的 treeitem,循环监听右键事件 const tree = document.querySelectorAll('#el-tree > [role="treeitem"]') tree.forEach(i => { this.contextMenuTarget_list.push(i) i.addEventListener('contextmenu',event => { // 如果右键了,则模拟点击这个treeitem event.target.click() }) }) }) },
同时时间是通过模拟点击这个treeitem实现的,所以可以在点击这个里面做判断,只有符合规则的节点才展示菜单
<context-menu class="right-menu" :target="contextMenuTarget" :show="contextMenuVisible" //即通过相关逻辑控制contextMenuVisible的值为true或者false
> <a href="javascript:;" @click="handleTransfer">{{operation[node_type]}}</a> </context-menu>
官方文档https://github.com/xunleif2e/vue-context-menu 是通过 @update:show来控制的,我们可以不用这个,直接用节点的点击事件即可,如下
handleNodeClick(data) { if (data.key.split('.').length == 2) { this.contextMenuVisible = true } else { this.contextMenuVisible = false } }
实现的效果,如下
其他参考: