chenyc
2025-10-14 a6f64303f88508d1c4d6ce53ff46be6b745cfb93
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<template>
    <transition name="el-zoom-in-center" ref="contextmenuRef">
        <div
            aria-hidden="true"
            class="el-dropdown__popper el-popper is-light is-pure custom-contextmenu"
            role="tooltip"
            data-popper-placement="bottom"
            :style="`top: ${dropdowns.y + 5}px;left: ${dropdowns.x}px;`"
            :key="Math.random()"
            v-show="state.isShow"
        >
            <ul class="el-dropdown-menu">
                <li
                    v-for="(v, k) in state.dropdownList"
                    class="el-dropdown-menu__item"
                    aria-disabled="false"
                    tabindex="-1"
                    :key="k"
                    @click="onCurrentClick(v.contextMenuClickId)"
                >
                    <SvgIcon :name="v.icon" />
                    <span>{{ v.txt }}{{ state.item.type === 'line' ? '线' : '节点' }}</span>
                </li>
            </ul>
            <div class="el-popper__arrow" style="left: 10px"></div>
        </div>
    </transition>
</template>
 
<script setup lang="ts" name="pagesWorkflowContextmenu">
import { computed, reactive, onMounted, onUnmounted, ref } from 'vue';
 
// 定义父组件传过来的值
const props = defineProps({
    dropdown: {
        type: Object,
        default: () => {
            return { x: '', y: '' };
        },
    },
});
 
// 定义子组件向父组件传值/事件
const emit = defineEmits(['current']);
 
// 定义变量内容
const contextmenuRef = ref();
const state = reactive({
    isShow: false,
    dropdownList: [
        { contextMenuClickId: 0, txt: '删除', icon: 'ele-Delete' },
        { contextMenuClickId: 1, txt: '编辑', icon: 'ele-Edit' },
    ],
    item: {
        type: 'node',
    },
    conn: {},
});
 
// 父级传过来的坐标 x,y 值
const dropdowns = computed(() => {
    return props.dropdown;
});
// 当前项菜单点击
const onCurrentClick = (contextMenuClickId: number) => {
    emit('current', Object.assign({}, { contextMenuClickId }, state.item), state.conn);
};
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
const openContextmenu = (item: WorkflowDrawerLabelType, conn = {}) => {
    state.item = item;
    state.conn = conn;
    closeContextmenu();
    setTimeout(() => {
        state.isShow = true;
    }, 10);
};
// 关闭右键菜单
const closeContextmenu = () => {
    state.isShow = false;
};
// 监听页面监听进行右键菜单的关闭
onMounted(() => {
    document.body.addEventListener('click', closeContextmenu);
    document.body.addEventListener('contextmenu', closeContextmenu);
});
// 页面卸载时,移除右键菜单监听事件
onUnmounted(() => {
    document.body.removeEventListener('click', closeContextmenu);
    document.body.removeEventListener('contextmenu', closeContextmenu);
});
 
// 暴露变量
defineExpose({
    openContextmenu,
});
</script>
 
<style scoped lang="scss">
.custom-contextmenu {
    transform-origin: center top;
    z-index: 2190;
    position: fixed;
    .el-dropdown-menu__item {
        font-size: 12px !important;
        white-space: nowrap;
        i {
            font-size: 12px !important;
        }
    }
}
</style>