ren
This commit is contained in:
92
src/components/tools/action-dropdown.vue
Normal file
92
src/components/tools/action-dropdown.vue
Normal file
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<el-dropdown
|
||||
v-if="hasVisibleItems"
|
||||
trigger="click"
|
||||
@command="handleCommand"
|
||||
:style="dropdownStyle"
|
||||
>
|
||||
<el-button
|
||||
:type="buttonType"
|
||||
link
|
||||
:style="buttonStyle"
|
||||
>
|
||||
<slot name="button">
|
||||
{{ buttonText }}
|
||||
<el-icon v-if="buttonIcon" class="el-icon--right" :style="iconStyle">
|
||||
<component :is="buttonIcon" v-if="buttonIcon" />
|
||||
</el-icon>
|
||||
</slot>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item
|
||||
v-for="item in visibleItems"
|
||||
:key="item.command"
|
||||
:command="item.command"
|
||||
>
|
||||
<el-icon v-if="item.icon">
|
||||
<component :is="item.icon" />
|
||||
</el-icon>
|
||||
<span :style="item.icon ? { marginLeft: '8px' } : {}">{{ item.label }}</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { Operation } from '@element-plus/icons-vue'
|
||||
|
||||
interface MenuItem {
|
||||
command: string
|
||||
label: string
|
||||
icon?: any
|
||||
visible?: boolean | (() => boolean)
|
||||
}
|
||||
|
||||
interface Props {
|
||||
items: MenuItem[]
|
||||
buttonText?: string
|
||||
buttonIcon?: any
|
||||
buttonType?: 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'text'
|
||||
buttonStyle?: string | Record<string, any>
|
||||
dropdownStyle?: string | Record<string, any>
|
||||
iconStyle?: string | Record<string, any>
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
buttonText: '更多',
|
||||
buttonIcon: Operation,
|
||||
buttonType: 'primary',
|
||||
buttonStyle: () => ({ whiteSpace: 'nowrap' }),
|
||||
dropdownStyle: () => ({ marginLeft: '12px' }),
|
||||
iconStyle: () => ({ marginLeft: '4px' })
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
command: [command: string]
|
||||
}>()
|
||||
|
||||
// 计算可见的菜单项
|
||||
const visibleItems = computed(() => {
|
||||
return props.items.filter(item => {
|
||||
if (item.visible === undefined) return true
|
||||
if (typeof item.visible === 'boolean') return item.visible
|
||||
if (typeof item.visible === 'function') return item.visible()
|
||||
return false
|
||||
})
|
||||
})
|
||||
|
||||
// 是否有可见的菜单项
|
||||
const hasVisibleItems = computed(() => {
|
||||
return visibleItems.value.length > 0
|
||||
})
|
||||
|
||||
// 处理命令
|
||||
const handleCommand = (command: string) => {
|
||||
emit('command', command)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user