<template> <div class="right-click-menu"> <div ref="RightMenuBody" class="right-menu-body" :style="styles" v-clickoutside="close" v-if="visible" > <ul> <li v-if="elementIsSelected" @click="toEdit"> <i class="el-icon-edit-outline"></i> 编辑 </li> <li v-if="elementIsSelected" class="li-danger" @click="toDelete"> <i class="el-icon-delete"></i> 删除 </li> <li v-if="elementIsSelected" @click="toCopy"> <i class="el-icon-copy-document"></i> 复制 </li> <li v-if="curCopyElement" @click="toPaste"> <i class="el-icon-document-copy"></i> 粘贴 </li> </ul> </div> </div> </template> <script> import { mapState, mapMutations, mapActions } from "vuex"; import Clickoutside from "element-ui/src/utils/clickoutside"; import { deepCopy, getElementId, randomCode } from "../../../plugins/utils"; export default { name: "right-click-menu", directives: { Clickoutside }, data() { return { visible: false, curColumnId: null, styles: { position: "fixed", zIndex: 3000, }, rightClickPos: {}, }; }, computed: { ...mapState("free", ["curElement", "curCopyElement"]), elementIsSelected() { return !!this.curElement.id; }, }, mounted() { this.init(); }, methods: { ...mapMutations("free", [ "setOpenElementEditDialog", "setCurElement", "setCurCopyElement", ]), ...mapActions("free", ["actElementById", "removeElement", "pasteElement"]), init() { // 注册自定义右键事件菜单 document.oncontextmenu = function () { return false; }; document.addEventListener("mouseup", this.docMouseUp); }, close() { this.visible = false; }, show() { this.visible = true; }, docMouseUp(e) { if (e.button === 2) { this.rightClick(e); } }, rightClick(e) { const { elementId, columnId } = this.getRelateElementId(e.target); // 栏外的点击,不做任何处理 if (!columnId) { this.curColumnId = null; this.setCurElement({}); this.rightClickPos = {}; return; } const { offsetLeft, offsetTop } = this.getOffsetInfo( e.target || e.srcElement ); this.rightClickPos = { x: offsetLeft + e.offsetX, y: offsetTop + e.offsetY, }; this.curColumnId = columnId; if (elementId) { this.actElementById(elementId); } else { this.setCurElement({}); } // 既没有要黏贴的元素也没有选中的元素时,不显示右键菜单 if (!this.curCopyElement.id && !this.curElement.id) return; this.show(); this.$nextTick(() => { const { x: clickLeft, y: clickTop } = e; const { offsetWidth: menuWidth, offsetHeight: menuHeight } = this.$refs.RightMenuBody; const { innerWidth: wWidth, innerHeight: wHeight } = window; let menuLeft = clickLeft, menuTop = clickTop; if (menuWidth + clickLeft > wWidth) { menuLeft = clickLeft - menuWidth; } if (menuHeight + clickTop > wHeight) { menuTop = clickTop - menuHeight; } this.styles = Object.assign({}, this.styles, { top: menuTop + "px", left: menuLeft + "px", }); }); }, getRelateElementId(dom) { let elementId = null, columnId = null; let parentNode = dom; while (!(columnId || parentNode.className.includes("page-box"))) { if ( !elementId && parentNode["id"] && parentNode["id"].includes("element-") ) { elementId = parentNode["id"]; } if ( !columnId && parentNode["id"] && parentNode["id"].includes("column-") ) { columnId = parentNode["id"]; } parentNode = parentNode.parentNode; } return { elementId, columnId }; }, getOffsetInfo(dom, endParentClass = "page-column-body") { let parentNode = dom; let offsetTop = 0, offsetLeft = 0; while (!parentNode.className.includes(endParentClass)) { offsetTop += parentNode.offsetTop; offsetLeft += parentNode.offsetLeft; parentNode = parentNode.offsetParent; } return { offsetLeft, offsetTop, }; }, toEdit() { this.close(); this.setOpenElementEditDialog(true); }, toDelete() { this.removeSelectElement(); // this.close(); // this.$confirm("确定要删除当前元素吗?", "提示", { // type: "warning" // }) // .then(() => { // this.removeSelectElement(); // }) // .catch(() => {}); }, removeSelectElement() { this.close(); this.removeElement(this.curElement); }, toCopy() { this.close(); this.setCurCopyElement(deepCopy(this.curElement)); }, toPaste() { this.close(); this.pasteElement({ element: { ...deepCopy(this.curCopyElement), ...this.rightClickPos, id: getElementId(), key: randomCode(), }, toColumnId: this.curColumnId, }); }, }, beforeDestroy() { document.oncontextmenu = null; document.removeEventListener("mouseup", this.docMouseUp); }, }; </script>