|
|
@@ -0,0 +1,108 @@
|
|
|
+<template>
|
|
|
+ <div class="app-menu-group">
|
|
|
+ <teleport to="body" v-if="type === 'contextmenu'">
|
|
|
+ <div class="app-menu-group__contextmenu" @contextmenu.prevent.capture @click="closeContextmenu"
|
|
|
+ v-show="contextmenuOptions.show">
|
|
|
+ <ul :style="styles">
|
|
|
+ <li :class="item.code" v-for="(item, index) in menus" :key="index"
|
|
|
+ @click.stop="onClick(item, index)">
|
|
|
+ <el-icon v-if="item.icon">
|
|
|
+ <component :is="item.icon" />
|
|
|
+ </el-icon>
|
|
|
+ <span>{{ item.title }}</span>
|
|
|
+ </li>
|
|
|
+ </ul>
|
|
|
+ </div>
|
|
|
+ </teleport>
|
|
|
+ <el-dropdown class="app-menu-group__dropdown" v-else-if="type === 'dropdown'">
|
|
|
+ <el-button type="info" icon="Setting" />
|
|
|
+ <template #dropdown>
|
|
|
+ <el-dropdown-menu>
|
|
|
+ <el-dropdown-item :class="item.code" v-for="(item, index) in menus" :key="index" :icon="item.icon"
|
|
|
+ @click="onClick(item, index)">
|
|
|
+ {{ item.title }}
|
|
|
+ </el-dropdown-item>
|
|
|
+ </el-dropdown-menu>
|
|
|
+ </template>
|
|
|
+ </el-dropdown>
|
|
|
+ <div class="app-menu-group__btnbar" v-else>
|
|
|
+ <template v-for="(item, index) in menus" :key="index">
|
|
|
+ <el-button :class="item.code" :type="item.buttonType" :disabled="activeName === item.code"
|
|
|
+ @click="onClick(item, index)" :link="linkButton">
|
|
|
+ <el-icon v-if="item.icon">
|
|
|
+ <component :is="item.icon" />
|
|
|
+ </el-icon>
|
|
|
+ <span v-if="item.title">{{ item.title }}</span>
|
|
|
+ </el-button>
|
|
|
+ </template>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script lang="ts" setup>
|
|
|
+import { shallowRef, computed, watch, PropType } from 'vue'
|
|
|
+
|
|
|
+interface ActionMenu {
|
|
|
+ name: string;
|
|
|
+ label: string;
|
|
|
+ type?: string;
|
|
|
+ className?: string;
|
|
|
+ icon?: string;
|
|
|
+ disabled?: boolean;
|
|
|
+ hide?: boolean;
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps({
|
|
|
+ // 操作菜单
|
|
|
+ menus: {
|
|
|
+ type: Array as PropType<Ermcp.UserMenu[]>,
|
|
|
+ required: true,
|
|
|
+ },
|
|
|
+ // 操作类型
|
|
|
+ type: {
|
|
|
+ type: String as PropType<'button' | 'dropdown' | 'contextmenu'>,
|
|
|
+ default: 'button',
|
|
|
+ },
|
|
|
+ // 右键菜单
|
|
|
+ contextmenu: {
|
|
|
+ type: Object as PropType<{ show: boolean; clientX: number; clientY: number; }>,
|
|
|
+ default: () => ({
|
|
|
+ show: false,
|
|
|
+ clientX: 0,
|
|
|
+ clientY: 0,
|
|
|
+ }),
|
|
|
+ },
|
|
|
+ // 链接按钮
|
|
|
+ linkButton: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ options: Object
|
|
|
+})
|
|
|
+
|
|
|
+const emit = defineEmits(['click'])
|
|
|
+const contextmenuOptions = shallowRef(props.contextmenu)
|
|
|
+const activeName = shallowRef('')
|
|
|
+
|
|
|
+// 右键菜单坐标
|
|
|
+const styles = computed(() => {
|
|
|
+ const { clientX, clientY } = contextmenuOptions.value
|
|
|
+ return {
|
|
|
+ left: clientX + 'px',
|
|
|
+ top: clientY + 'px',
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+// 关闭右键菜单
|
|
|
+const closeContextmenu = () => {
|
|
|
+ contextmenuOptions.value.show = false
|
|
|
+}
|
|
|
+
|
|
|
+const onClick = (item: Ermcp.UserMenu, index: number) => {
|
|
|
+ activeName.value = item.code
|
|
|
+ closeContextmenu()
|
|
|
+ emit('click', activeName.value, props.options, index)
|
|
|
+}
|
|
|
+
|
|
|
+watch(() => props.contextmenu, (options) => contextmenuOptions.value = options)
|
|
|
+</script>
|