mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	refactor: 界面优化
This commit is contained in:
		
							
								
								
									
										135
									
								
								mayfly_go_web/src/components/contextmenu/index.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										135
									
								
								mayfly_go_web/src/components/contextmenu/index.vue
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,135 @@
 | 
			
		||||
<template>
 | 
			
		||||
    <transition name="el-zoom-in-center">
 | 
			
		||||
        <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">
 | 
			
		||||
                <template v-for="(v, k) in state.dropdownList">
 | 
			
		||||
                    <li class="el-dropdown-menu__item" aria-disabled="false" tabindex="-1" :key="k" v-if="!v.affix"
 | 
			
		||||
                        @click="onCurrentContextmenuClick(v.contextMenuClickId)">
 | 
			
		||||
                        <SvgIcon :name="v.icon" />
 | 
			
		||||
                        <span>{{ v.txt }}</span>
 | 
			
		||||
                    </li>
 | 
			
		||||
                </template>
 | 
			
		||||
            </ul>
 | 
			
		||||
            <div class="el-popper__arrow" :style="{ left: `${state.arrowLeft}px` }"></div>
 | 
			
		||||
        </div>
 | 
			
		||||
    </transition>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script setup lang="ts" name="layoutTagsViewContextmenu">
 | 
			
		||||
import { computed, reactive, onMounted, onUnmounted, watch } from 'vue';
 | 
			
		||||
 | 
			
		||||
// 定义父组件传过来的值
 | 
			
		||||
const props = defineProps({
 | 
			
		||||
    dropdown: {
 | 
			
		||||
        type: Object,
 | 
			
		||||
        default: () => {
 | 
			
		||||
            return {
 | 
			
		||||
                x: 0,
 | 
			
		||||
                y: 0,
 | 
			
		||||
            };
 | 
			
		||||
        },
 | 
			
		||||
    },
 | 
			
		||||
    items: {
 | 
			
		||||
        type: Array,
 | 
			
		||||
        default: [],
 | 
			
		||||
    },
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 定义子组件向父组件传值/事件
 | 
			
		||||
const emit = defineEmits(['currentContextmenuClick']);
 | 
			
		||||
 | 
			
		||||
// 定义变量内容
 | 
			
		||||
const state = reactive({
 | 
			
		||||
    isShow: false,
 | 
			
		||||
    dropdownList: [
 | 
			
		||||
        { contextMenuClickId: 0, txt: '刷新', affix: false, icon: 'RefreshRight' },
 | 
			
		||||
        { contextMenuClickId: 1, txt: '关闭', affix: false, icon: 'Close' },
 | 
			
		||||
        { contextMenuClickId: 2, txt: '关闭其他', affix: false, icon: 'CircleClose' },
 | 
			
		||||
        { contextMenuClickId: 3, txt: '关闭所有', affix: false, icon: 'FolderDelete' },
 | 
			
		||||
    ],
 | 
			
		||||
    item: {} as any,
 | 
			
		||||
    arrowLeft: 10,
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
// 父级传过来的坐标 x,y 值
 | 
			
		||||
const dropdowns = computed(() => {
 | 
			
		||||
    // 117 为 `Dropdown 下拉菜单` 的宽度
 | 
			
		||||
    if (props.dropdown.x + 117 > document.documentElement.clientWidth) {
 | 
			
		||||
        return {
 | 
			
		||||
            x: document.documentElement.clientWidth - 117 - 5,
 | 
			
		||||
            y: props.dropdown.y,
 | 
			
		||||
        };
 | 
			
		||||
    } else {
 | 
			
		||||
        return props.dropdown;
 | 
			
		||||
    }
 | 
			
		||||
});
 | 
			
		||||
// 当前项菜单点击
 | 
			
		||||
const onCurrentContextmenuClick = (contextMenuClickId: number) => {
 | 
			
		||||
    emit('currentContextmenuClick', { id: contextMenuClickId, item: state.item });
 | 
			
		||||
};
 | 
			
		||||
// 打开右键菜单:判断是否固定,固定则不显示关闭按钮
 | 
			
		||||
const openContextmenu = (item: any) => {
 | 
			
		||||
    state.item = item;
 | 
			
		||||
    closeContextmenu();
 | 
			
		||||
    setTimeout(() => {
 | 
			
		||||
        state.isShow = true;
 | 
			
		||||
    }, 10);
 | 
			
		||||
};
 | 
			
		||||
// 关闭右键菜单
 | 
			
		||||
const closeContextmenu = () => {
 | 
			
		||||
    state.isShow = false;
 | 
			
		||||
};
 | 
			
		||||
// 监听页面监听进行右键菜单的关闭
 | 
			
		||||
onMounted(() => {
 | 
			
		||||
    document.body.addEventListener('click', closeContextmenu);
 | 
			
		||||
});
 | 
			
		||||
// 页面卸载时,移除右键菜单监听事件
 | 
			
		||||
onUnmounted(() => {
 | 
			
		||||
    document.body.removeEventListener('click', closeContextmenu);
 | 
			
		||||
});
 | 
			
		||||
// 监听下拉菜单位置
 | 
			
		||||
watch(
 | 
			
		||||
    () => props.dropdown,
 | 
			
		||||
    ({ x }) => {
 | 
			
		||||
        if (x + 117 > document.documentElement.clientWidth) state.arrowLeft = 117 - (document.documentElement.clientWidth - x);
 | 
			
		||||
        else state.arrowLeft = 10;
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        deep: true,
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
watch(
 | 
			
		||||
    () => props.items,
 | 
			
		||||
    (x: any) => {
 | 
			
		||||
        state.dropdownList = x
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
        deep: true,
 | 
			
		||||
    }
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
// 暴露变量
 | 
			
		||||
defineExpose({
 | 
			
		||||
    openContextmenu,
 | 
			
		||||
    closeContextmenu,
 | 
			
		||||
});
 | 
			
		||||
</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>
 | 
			
		||||
		Reference in New Issue
	
	Block a user