| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <template>
- <div class="app-action-menu">
- <teleport to="body" v-if="type === 'contextmenu'">
- <div class="app-action-menu__contextmenu" @contextmenu.prevent.capture @click="closeContextmenu"
- v-show="contextmenuOptions.show">
- <ul :style="styles">
- <li :class="item.className" v-for="(item, index) in actionMenus" :key="index"
- @click.stop="onClick(item, index)">
- <el-icon v-if="item.icon">
- <component :is="item.icon" />
- </el-icon>
- <span>{{ item.label }}</span>
- </li>
- </ul>
- </div>
- </teleport>
- <el-dropdown trigger="click" class="app-action-menu__dropdown" v-else-if="type === 'dropdown'">
- <el-button size="small" icon="MoreFilled" round />
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item :class="item.className" v-for="(item, index) in actionMenus" :key="index"
- :icon="item.icon" @click.stop="onClick(item, index)">
- {{ item.label }}
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <div class="app-action-menu__btnbar" v-else>
- <template v-for="(item, index) in actionMenus" :key="index">
- <el-button :class="item.className" :type="item.type" :disabled="item.disabled"
- @click.stop="onClick(item, index)" :link="linkButton">
- <el-icon v-if="item.icon">
- <component :is="item.icon" />
- </el-icon>
- <span v-if="item.label">{{ item.label }}</span>
- </el-button>
- </template>
- </div>
- </div>
- </template>
- <script lang="ts" setup>
- import { ref, shallowRef, computed, PropType, watchEffect } from 'vue'
- import { ActionMenu } from './interface'
- 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,
- },
- record: Object,
- })
- const emit = defineEmits(['click'])
- const contextmenuOptions = shallowRef(props.contextmenu)
- const actionMenus = ref<ActionMenu[]>([])
- // 右键菜单坐标
- const styles = computed(() => {
- const { clientX, clientY } = contextmenuOptions.value
- return {
- left: clientX + 'px',
- top: clientY + 'px',
- }
- })
- // 关闭右键菜单
- const closeContextmenu = () => {
- contextmenuOptions.value.show = false
- }
- const onClick = (item: ActionMenu, index: number) => {
- item.record = props.record
- closeContextmenu()
- emit('click', item, index)
- }
- watchEffect(() => {
- actionMenus.value = props.menus.map((e) => ({
- name: e.code,
- label: e.title,
- icon: e.icon,
- className: e.className,
- hide: e.hidden,
- }))
- contextmenuOptions.value = props.contextmenu
- })
- </script>
- <style lang="less">
- @import './index.less';
- </style>
|