vue实现自定义全局右键菜单

前段时间公司在做一个webIDE项目,其中有对文件树的各种操作,主要通过右键菜单实现,今天就来记录一下怎么在vue项目中实现全局的自定义右键菜单。效果如图所示:

注意:

需要在项目中找到页面整体布局的组件,比如项目使用Home.vue作为整个项目的公共布局,将根元素定位设置成relative,使右键菜单相对于其进行定位。

本文的右键菜单主要使用vuex实现

一、vuex中定义全局状态用于管理右键菜单

export default {
    /**
     * menuContent格式:
     * [
     *      {
     *          name: '新建文件',   // 操作名
     *          method: 'createDirectory',  // 需要执行的对应组件中的方法
     *             disabled: true        // 是否禁用,可以根据页面具体逻辑进行调整
     *      }
     * ]
     * 
     * 
     * 整体右键菜单采用绝对定位,所以clientX、clientY代表是left和top定位
     */
    state: {
        menuContent: [],    // 右键菜单内容
        clientX: '',    // left
        clientY: '',    // top
        displayContextMenu: false   // 是否展示右键菜单
    },
    mutations: {
        SET_CONTEXT_MENU: (state, payload) => {
            state.menuContent = payload.menuContent;
            state.clientX = payload.clientX;
            state.clientY = payload.clientY;
            state.displayContextMenu = payload.displayContextMenu;
        },
    }
}

二、定义公共组件ContextMenu.vue

<template>
    <div class="context-menu" v-show="contextMenu.displayContextMenu" 
        :style="{'left': contextMenu.clientX + 'px', 'top': contextMenu.clientY + 'px'}">
        <ul>
            <li v-for="(item, i) in contextMenu.menuContent" :key="i" :class="item.disabled ? 'disabled' : ''" 
                @click="emitEvent(item.method)">
                {{item.name}}
            </li>
        </ul>
    </div>
</template>

<script>
import { mapState } from 'vuex';
import bus from '@/views/common/bus';
export default {
    name: 'ContextMenu',
    data(){
        return {
        }
    },
    computed: {
        ...mapState(['contextMenu'])
    },
    methods: {
        emitEvent(type){
            bus.$emit('operateDirectory', type)
        }
    }
}
</script>

<style lang="scss" scoped>
    .context-menu {
        position: absolute;
        background: #FFF;
        color: #34495E;
        min-width: 100px;
        box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);
        border-radius: 2px;
        cursor: pointer;
        z-index: 1002;
        &>ul {
            text-align: left;
            padding: 5px 10px;
            &>li {
                padding: 3px 4px;
                font-size: 12px;
                list-style: none;
                height: 24px;
                line-height: 24px;
                &:hover {
                    background: #EDF6FF;
                }
            }
            .disabled {
                color: #888585;
                pointer-events: none;
            }
        }
    }
</style>

三、在组件中使用

import { mapState } from 'vuex';
// ...

computed: {
    ...mapState(['contextMenu'])
},
created(){
    bus.$on('operateDirectory', (param) => {
    // 点击右键菜单时,应触发组件内的同名方法,首先应判断该方法是否在本组件内存在,存在则调用
        if(this[param]){
            this[param]();
        }
    });
},
// ...

methods: {
    showContextMenu(event, data) {
        event.preventDefault();        // 阻止浏览器的默认事件
        const menuContent = {
            menuContent: [
            {
                icon: "el-icon-upload2",
                name: "运行",
                method: "run",
            },
            {
                icon: "el-icon-refresh",
                name: "编辑",
                method: "editConfig",
            },
            {
                icon: "el-icon-refresh",
                name: "添加",
                method: "addCommond",
            },
            {
                icon: "el-icon-refresh",
                name: "删除",
                method: "deleteConfig",
            },
            ],
            clientX: event.clientX,
            clientY: event.clientY,
            displayContextMenu: true,
        };
        this.$store.commit("SET_CONTEXT_MENU", menuContent);
        // 再次点击页面,右键菜单消失
        document.onclick = (event) => {
            this.$store.commit("SET_CONTEXT_MENU", {
                displayContextMenu: false,
            });
        };
    },
    run(){
        // ...
    },
    editConfig(){
        // ...
    },
    addCommond(){
        // ...
    },
    deleteConfig(){
        // ...
    }
}

总结

这种可以实现全局右键菜单,并且支持自定义右键内容,但是vue3.0对event bus的取消会导致不可用。

目前有一种优化方法:项目中对应会使用组件库,例如element ui,在定义contextMenu.vue的时候,使用dialog,将内容定义在Popover 弹出框中,当组件使用右键菜单时,使用子组件的方式使用ContextMenu.vue,点击右键菜单内容时就不需要使用emit触发了。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Vue中Table组件行内右键菜单实现方法(基于 vue + AntDesign)

    最近做的一个项目是基于 vue + AntDesign 的.由于项目要求,需要在 Table 组件的行内点右键的时候弹出菜单.在线演示地址及最终效果图如下: 在线演示地址>> 首先新建一个Table组件的实例: <a-table :columns="columns" :rowKey="record => { return record.INDEX;}" :dataSource="tableData" /> ... c

  • 1分钟Vue实现右键菜单

    目录 效果图 安装 代码实现 自定义样式 总结 高效实现需求,避免重复造轮子.今天给大家分享的是,如何在最短的时候内实现右键菜单.方法也很简单,一个插件就可以搞定,话不多说,上效果图: 效果图 安装 npm install vue-contextmenujs 或 yarn add vue-contextmenujs 使用 import Contextmenu from "vue-contextmenujs" Vue.use(Contextmenu); 代码实现 以element-ui图

  • vue 右键菜单插件 简单、可扩展、样式自定义的右键菜单

    今天分享的不是技术,今天给大家分享个插件,针对现有的vue右键菜单插件,大多数都是需要使用插件本身自定义的标签,很多地方不方便,可扩展性也很低,所以我决定写了一款自定义指令调用右键菜单(vuerightmenu) 安装  npm install rightmenu --save-dev   开始 //main.js import vue from "vue"; import rightMenu from "rightMenu"; vue.use(rightMenu)

  • vue中如何自定义右键菜单详解

    在所编辑的页面,需要添加右键菜单的元素,绑定contextmenu事件,如下: <li v-for="item in resourceList" :key="item.id" @click="handleClickFolder(item)" @contextmenu.prevent="openMenu($event,item)" > </li> 在页面编写右键菜单内容: <ul v-show=&q

  • vue右键菜单的简单封装

    本文实例为大家分享了vue实现右键菜单封装的具体代码,供大家参考,具体内容如下 封装一个简单的右键菜单,要求右键处出现菜单,点击除了菜单部分可以关闭菜单. 组件 <template>   <div class="ContextMenu" @click="close" v-show="show">     <ul class="menuMain" ref="menuMain" :

  • 原生Vue 实现右键菜单组件功能

    Vue 原生实现右键菜单组件, 零依赖 快速安装 npm install vue-contextmenujs 使用 测试中使用的是 element-ui 图标 import Contextmenu from "vue-contextmenujs" Vue.use(Contextmenu); <template> <div id="app" style="width:100vw;height:100vh" @contextmenu

  • vue添加自定义右键菜单的完整实例

    一.写原生方法 1.在所编辑的页面,需要添加右键菜单的元素,绑定contextmenu事件,如下: <li v-for="item in resourceList" :key="item.id" @click="handleClickFolder(item)" @contextmenu.prevent="openMenu($event,item)" > ... </li> 2.在页面编写右键菜单内容:

  • Vue+element-ui添加自定义右键菜单的方法示例

    1.在所编辑的页面,需要添加右键菜单的元素,绑定contextmenu事件 <template> <el-button size="medium" @contextmenu.prevent.native="openMenu($event)"> ...... </template> 2.在页面编写右键菜单内容 <ul v-show="visible" :style="{left:left+'px'

  • vue实现自定义全局右键菜单

    前段时间公司在做一个webIDE项目,其中有对文件树的各种操作,主要通过右键菜单实现,今天就来记录一下怎么在vue项目中实现全局的自定义右键菜单.效果如图所示: 注意: 需要在项目中找到页面整体布局的组件,比如项目使用Home.vue作为整个项目的公共布局,将根元素定位设置成relative,使右键菜单相对于其进行定位. 本文的右键菜单主要使用vuex实现 一.vuex中定义全局状态用于管理右键菜单 export default {     /**      * menuContent格式:  

  • javascript全局自定义鼠标右键菜单

    本文实例为大家分享了javascript全局自定义鼠标右键菜单的具体代码,供大家参考,具体内容如下 前言 html全局自定义鼠标右键菜单 一.效果展示 二.源代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> #TextBox{ width: 2

  • Vue实现自定义下拉菜单功能

    先看例子,后面有对用到的知识点的总结 效果图: 实现代码如下: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>组件练习</title> <link rel="stylesheet" type="text/css" href="component.c

  • javascript局部自定义鼠标右键菜单

    本文实例为大家分享了js局部自定义鼠标右键菜单的具体代码,供大家参考,具体内容如下 前言 html局部自定义鼠标右键菜单 局部! 局部! 局部! 重要的关键词说三遍! 一.效果展示 二.源代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> #Te

  • JQuery模拟实现网页中自定义鼠标右键菜单功能

    前言 题外话.......最近在开发一个网站项目的时候,需要用到网页自定义右键菜单,在网上看了各路前辈大神的操作,头晕目眩,为了达到目的,突然灵机一动,于是便有了这篇文章. 先放个效果图(沾沾自喜,大神勿喷): 废话不多说,进入正题: 1.首先 我们要禁用掉原网页中右键菜单 //JQuery代码 $(selector).on('contextmenu', function () { return false; }) 这样目标区域的右键菜单就无法使用了 demo1: <!DOCTYPE html>

  • Vue中自定义全局组件的实现方法

    前言 有时候我们在做开发的时候,就想自己写一个插件然后就可以使用自己的插件,那种成就感很强.今天就解决了一个长期困扰着我的问题,现在记录一下,供日后参考. 涉及知识点是Vue.js官网教程中的插件使用 方法如下: 首先我遇到的问题就是我自定义的组件如果需要在项目中其他组件中多次被调用,而我之前的解决方法就是简单的,哪里需要在哪引用.这无疑增加了许多代码重复. 而在使用Vue.js的一些UI框架的时候则注意到,只需要在项目的入口文件中import这个插件然后在接着Vue.use('插件名').这样

  • jquery实现在网页指定区域显示自定义右键菜单效果

    本文实例讲述了jquery实现在网页指定区域显示自定义右键菜单效果.分享给大家供大家参考.具体如下: 这是一个jquery实现的网页右键菜单效果,与其它自定义的右键菜单不同之处在于,本菜单只在指定区域内才有效,若超出指定区域的话,点击右键后显示的仍是浏览器的右键菜单.运行效果后,请在橘色区域内点击鼠标右键,会弹出一个带图标的自定义右键菜单,和浏览器的右键菜单完全不一样哦! 运行效果截图如下: 在线演示地址如下: http://demo.jb51.net/js/2015/jquery-web-ar

  • vue自定义全局组件(自定义插件)的用法

    有时候我们在做开发的时候,就想自己写一个插件然后就可以使用自己的插件,那种成就感很强.博主最近研究element-ui和axios的时候,发现他们是自定义组件,但是唯一有一点不同的是,在用element-ui的时候是使用Vue.use()语句来使用的,而axios的时候,不用Vue.use(),只要import就可以导入进来了,感觉很神奇,细细的发现,原来他们的不同是因为axios里面并没有写install方法,而element-ui就有写这个方法,下面就利用这个install来写一个自己的插件

  • JS自定义右键菜单实现代码解析

    今天来讲一个关于右键菜单的小demo,抛砖引玉. 首先,我们要用css和html做一个自定义右键菜单. <!--自定义右键菜单html代码--> <div id="menu"> <div class="menu">功能1</div> <div class="menu">功能2</div> <div class="menu">功能3</di

随机推荐