├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── .prettierrc.json ├── PUBLISH.md ├── README.md ├── babel.config.js ├── commitlint.config.js ├── package.json ├── src ├── components │ └── right-menu.vue └── main.js ├── vue.config.js ├── webstorm.config.js └── yarn.lock /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not dead 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | # 对所有文件有效 4 | [*] 5 | charset = utf-8 6 | tab_width = 2 7 | indent_style = space 8 | indent_size = 2 -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | env: { 4 | node: true 5 | }, 6 | extends: ["plugin:vue/essential", "eslint:recommended", "@vue/prettier"], 7 | parserOptions: { 8 | parser: "babel-eslint" 9 | }, 10 | rules: { 11 | "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", 12 | "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", 13 | "prettier/prettier": "error", // prettier标记的地方抛出错误信息 14 | "spaced-comment": [2, "always"], // 注释后面必须写两个空格 15 | "@typescript-eslint/no-explicit-any": ["off"] // 关闭any校验 16 | } 17 | }; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | 6 | # local env files 7 | .env.local 8 | .env.*.local 9 | 10 | # Log files 11 | npm-debug.log* 12 | yarn-debug.log* 13 | yarn-error.log* 14 | pnpm-debug.log* 15 | 16 | # Editor directories and files 17 | .idea 18 | .vscode 19 | *.suo 20 | *.ntvs* 21 | *.njsproj 22 | *.sln 23 | *.sw? 24 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth": 2, 3 | "useTabs": false, 4 | "endOfLine": "auto", 5 | "singleQuote": false, 6 | "semi": true, 7 | "trailingComma": "none", 8 | "bracketSpacing": true 9 | } 10 | -------------------------------------------------------------------------------- /PUBLISH.md: -------------------------------------------------------------------------------- 1 | ## 新版本推送规范 2 | 3 | - 对插件进行修改 4 | 5 | - 执行 `yarn build` 来生成打包后的文件 6 | 7 | - 修改`package.json`中的版本号 8 | 9 | - 提交你的修改 10 | 11 | - 运行`package.json`中的`changelog`命令来生成更新记录 12 | 13 | - 最后将项目推送到你的仓库,然后为主仓库创建一个Pull request 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vue-right-click-menu · [![npm](https://img.shields.io/badge/npm-v1.1.1-2081C1)](https://www.npmjs.com/package/vue-right-click-menu) [![yarn](https://img.shields.io/badge/yarn-v1.1.1-F37E42)](https://yarnpkg.com/package/vue-right-click-menu) [![github](https://img.shields.io/badge/GitHub-depositary-9A9A9A)](https://github.com/likaia/vue-right-click-menu) [![](https://img.shields.io/github/issues/likaia/vue-right-click-menu)](https://github.com/likaia/vue-right-click-menu/issues) [![]( https://img.shields.io/github/forks/likaia/vue-right-click-menu)](https://github.com/likaia/vue-right-click-menu/network/members) [![]( https://img.shields.io/github/stars/likaia/vue-right-click-menu)](https://github.com/likaia/vue-right-click-menu/stargazers) 2 | 支持vue的浏览器右键菜单插件,效果图如下: 3 | 4 | ![](https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0261ae22733144a6ac67ec16008355d2~tplv-k3u1fbpfcp-watermark.image) 5 | 6 | ## 插件安装 7 | ```bash 8 | yarn add vue-right-click-menu 9 | 10 | # or 11 | 12 | npm install vue-right-click-menu --save 13 | ``` 14 | ## 插件使用 15 | 16 | * 在项目的入口文件`main.ts/main.js`中加入下述代码 17 | ```javascript 18 | import rightMenu from "vue-right-click-menu"; 19 | 20 | Vue.use(rightMenu); 21 | ``` 22 | * 在你的业务代码中,在元素上绑定`v-right-click`,然后传对应的参数即可. 23 | ```vue 24 | 30 | 72 | ``` 73 | ### 参数说明 74 | 如示例代码所示,在元素上绑定指令,在computed中定义一个对象,传菜单内容和与之对应的事件处理函数就可以了。 75 | 76 | 接下来就跟大家讲下对象里每个属性的意义: 77 | * this 即当前vue实例,便于在处理函数中能访问到当前vue实例中的内容 78 | * text 类型为数组,即右键菜单要显示的内容 79 | * 数组内的内容分为字符串或对象,如果为字符串这一项默认是可以点击的 80 | * 如果你想让某个选项无法点击,则传一个对象 81 | * content 要显示的文字内容,字符串类型 82 | * status 是否禁用,boolean类型 83 | * 点击事件接受一个参数,具体写法可参考示例代码 84 | * handler 事件处理函数,函数的顺序要与text数组内的文本顺序相对应 85 | 86 | ## 写在最后 87 | 至此,插件的所有使用方法就介绍完了。 88 | 89 | 该插件仅支持Vue2.x的项目,Vue3.x项目请移步: [vue-right-click-menu-next](https://github.com/likaia/vue-right-click-menu-next) 90 | 91 | 想进一步了解插件源码的请移步插件的GitHub仓库:[vue-right-click-menu](https://github.com/likaia/vue-right-click-menu) 92 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ["@vue/cli-plugin-babel/preset"] 3 | }; 4 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { extends: ["@commitlint/config-angular"] }; 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-right-click-menu", 3 | "version": "1.1.1", 4 | "description": "支持vue的右键菜单插件", 5 | "private": false, 6 | "main": "dist/vueRightMenuPlugin.common.js", 7 | "publisher": "magicalprogrammer@qq.com", 8 | "scripts": { 9 | "build": "vue-cli-service build --target lib --name vueRightMenuPlugin src/main.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/likaia/vue-right-click-menu.git" 14 | }, 15 | "keywords": [ 16 | "vuejs", 17 | "vue", 18 | "rightMenu", 19 | "右键菜单", 20 | "vueRightMenu" 21 | ], 22 | "author": "likaia", 23 | "license": "MIT", 24 | "bugs": { 25 | "url": "https://github.com/likaia/vue-right-click-menu/issues" 26 | }, 27 | "homepage": "https://github.com/likaia/vue-right-click-menu#readme", 28 | "dependencies": { 29 | "core-js": "^3.6.5", 30 | "vue": "^2.6.11" 31 | }, 32 | "devDependencies": { 33 | "@vue/cli-plugin-babel": "~4.5.0", 34 | "@vue/cli-plugin-eslint": "~4.5.0", 35 | "@vue/cli-service": "~4.5.0", 36 | "@vue/eslint-config-prettier": "^6.0.0", 37 | "babel-eslint": "^10.1.0", 38 | "eslint": "^6.7.2", 39 | "eslint-plugin-prettier": "^3.1.3", 40 | "eslint-plugin-vue": "^6.2.2", 41 | "node-sass": "^4.12.0", 42 | "prettier": "^1.19.1", 43 | "sass-loader": "^8.0.2", 44 | "vue-template-compiler": "^2.6.11" 45 | }, 46 | "config": { 47 | "commitizen": { 48 | "path": "./node_modules/cz-conventional-changelog" 49 | } 50 | }, 51 | "husky": { 52 | "hooks": { 53 | "commit-msg": "commitlint -E HUSKY_GIT_PARAMS" 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/components/right-menu.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 69 | 70 | 133 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import rightMenu from "./components/right-menu.vue"; 2 | import Vue from "vue"; 3 | 4 | // 挂载后的dom节点 5 | let menuVM = null; 6 | 7 | /** 8 | * 将组件挂在到节点上 9 | * @param comp 需要挂载的组件 10 | * @param prop 向组件传的参数 11 | */ 12 | const creatComp = function(comp, prop) { 13 | // 创建组件 14 | const app = Vue.extend(comp); 15 | // 创建一个div元素 16 | const divEle = document.createElement("div"); 17 | // 将创建的div元素挂载追加至body里 18 | document.body.appendChild(divEle); 19 | // 将组件挂载至刚才创建的div中, 使用propsData进行传参 20 | new app({ 21 | propsData: { 22 | ...prop 23 | } 24 | }).$mount(divEle); 25 | // 返回挂载的元素,便于操作 26 | return divEle; 27 | }; 28 | 29 | export default { 30 | install(Vue) { 31 | // 监听全局点击,销毁右键菜单dom 32 | document.body.addEventListener("click", () => { 33 | if (menuVM != null) { 34 | // 销毁右键菜单DOM 35 | document.body.removeChild(document.getElementById("rightMenuDom")); 36 | menuVM = null; 37 | } 38 | }); 39 | Vue.directive("rightClick", (el, binding) => { 40 | // 指令绑定元素元素是否存在判断 41 | if (el == null) { 42 | throw "右键指令错误:元素未绑定"; 43 | } 44 | el.oncontextmenu = function(e) { 45 | if (menuVM != null) { 46 | // 销毁上次触发的右键菜单DOM 47 | document.body.removeChild(document.getElementById("rightMenuDom")); 48 | menuVM = null; 49 | } 50 | const textArray = binding.value.text; 51 | const handlerObj = binding.value.handler; 52 | const parameter = binding.arg; 53 | // 菜单选项与事件处理函数是否存在 54 | if (textArray == null || handlerObj == null) { 55 | throw "右键菜单内容与事件处理函数为必传项"; 56 | } 57 | // 事件处理数组 58 | const handlerArray = []; 59 | // 处理好的右键菜单 60 | const menuList = []; 61 | // 将事件处理函数放入数组中 62 | for (const key in handlerObj) { 63 | handlerArray.push(handlerObj[key]); 64 | } 65 | if (textArray.length !== handlerArray.length) { 66 | // 文本数量与事件处理不对等 67 | throw "右键菜单的每个选项,都必须有它的事件处理函数"; 68 | } 69 | // 追加右键菜单数据 70 | for (let i = 0; i < textArray.length; i++) { 71 | // 右键菜单对象, 添加名称 72 | const menuObj = { 73 | text: textArray[i], 74 | handler: handlerArray[i], 75 | id: i + 1 76 | }; 77 | // 动态参数不为空则追加 78 | if (parameter != null) { 79 | menuObj.parameter = parameter; 80 | } 81 | menuList.push(menuObj); 82 | } 83 | // 鼠标点的坐标 84 | const oX = e.clientX; 85 | const oY = e.clientY; 86 | // 动态挂载组件,显示右键菜单 87 | menuVM = creatComp(rightMenu, { 88 | rightMenuStatus: "block", 89 | rightMenuTop: oY + "px", 90 | rightMenuLeft: oX + "px", 91 | rightMenuList: menuList 92 | }); 93 | return false; 94 | }; 95 | }); 96 | } 97 | }; 98 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // 强制css内联,不然会导致样式失效问题 3 | css: { extract: false }, 4 | parallel: false 5 | }; 6 | -------------------------------------------------------------------------------- /webstorm.config.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | // eslint-disable-next-line @typescript-eslint/no-var-requires 3 | const path = require("path"); 4 | 5 | function resolve(dir) { 6 | return path.join(__dirname, ".", dir); 7 | } 8 | 9 | module.exports = { 10 | context: path.resolve(__dirname, "./"), 11 | resolve: { 12 | extensions: [".js", ".vue", ".json"], 13 | alias: { 14 | "@": resolve("src"), 15 | "@views": resolve("src/views"), 16 | "@comp": resolve("src/components"), 17 | "@core": resolve("src/core"), 18 | "@utils": resolve("src/utils") 19 | } 20 | } 21 | }; 22 | --------------------------------------------------------------------------------