220 lines
4.1 KiB
Vue

<template>
<component :is="iconComponent" :class="['app-icon', sizeClass]" :style="iconStyle" />
</template>
<script setup lang="ts">
import { computed } from 'vue'
import {
// 常用图标
HomeIcon,
DocumentTextIcon,
ClipboardDocumentListIcon,
UserGroupIcon,
ChartBarIcon,
BellIcon,
CalendarIcon,
TrophyIcon,
Cog6ToothIcon,
UserIcon,
ArrowRightOnRectangleIcon,
CheckCircleIcon,
XCircleIcon,
InformationCircleIcon,
StarIcon,
FireIcon,
ArrowTrendingUpIcon,
ShareIcon,
PlusIcon,
PencilIcon,
TrashIcon,
ClockIcon,
InboxIcon,
CheckIcon,
ExclamationTriangleIcon,
MagnifyingGlassIcon,
FunnelIcon,
XMarkIcon,
EyeIcon,
EyeSlashIcon,
LockClosedIcon,
LockOpenIcon,
EnvelopeIcon,
PhoneIcon,
BuildingOfficeIcon,
TagIcon,
PhotoIcon,
VideoCameraIcon,
DocumentIcon,
LinkIcon,
ArrowDownTrayIcon,
ArrowUpTrayIcon,
PlayIcon,
PauseIcon,
StopIcon,
ArrowPathIcon,
ArrowUturnLeftIcon,
ArrowUturnRightIcon,
ChevronLeftIcon,
ChevronRightIcon,
ChevronUpIcon,
ChevronDownIcon,
Bars3Icon,
BoltIcon,
SparklesIcon,
FolderIcon,
ComputerDesktopIcon,
FlagIcon
} from '@heroicons/vue/24/outline'
import { BellIcon as BellSolidIcon } from '@heroicons/vue/24/solid'
export interface IconProps {
name: string
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
color?: string
}
const props = withDefaults(defineProps<IconProps>(), {
size: 'md',
color: 'currentColor'
})
// 图标映射表
const iconMap: Record<string, any> = {
// 导航和基础
home: HomeIcon,
document: DocumentTextIcon,
clipboard: ClipboardDocumentListIcon,
list: ClipboardDocumentListIcon,
users: UserGroupIcon,
chart: ChartBarIcon,
bell: BellIcon,
bellSolid: BellSolidIcon,
calendar: CalendarIcon,
trophy: TrophyIcon,
settings: Cog6ToothIcon,
user: UserIcon,
logout: ArrowRightOnRectangleIcon,
// 状态
check: CheckIcon,
checkCircle: CheckCircleIcon,
xCircle: XCircleIcon,
info: InformationCircleIcon,
warning: ExclamationTriangleIcon,
star: StarIcon,
fire: FireIcon,
bolt: BoltIcon,
sparkles: SparklesIcon,
history: ClockIcon,
crown: SparklesIcon, // 使用 sparkles 作为 crown 的替代
rise: ArrowTrendingUpIcon, // 使用 trendUp 作为 rise 的替代
// 操作
plus: PlusIcon,
edit: PencilIcon,
delete: TrashIcon,
share: ShareIcon,
search: MagnifyingGlassIcon,
filter: FunnelIcon,
close: XMarkIcon,
eye: EyeIcon,
eyeSlash: EyeSlashIcon,
lock: LockClosedIcon,
locked: LockClosedIcon, // 别名
unlock: LockOpenIcon,
// 内容
inbox: InboxIcon,
clock: ClockIcon,
email: EnvelopeIcon,
phone: PhoneIcon,
building: BuildingOfficeIcon,
tag: TagIcon,
photo: PhotoIcon,
image: PhotoIcon, // 别名
video: VideoCameraIcon,
file: DocumentIcon,
link: LinkIcon,
folder: FolderIcon,
monitor: ComputerDesktopIcon,
target: FlagIcon,
// 方向
arrowUp: ChevronUpIcon,
arrowDown: ChevronDownIcon,
arrowLeft: ChevronLeftIcon,
arrowRight: ChevronRightIcon,
trendUp: ArrowTrendingUpIcon,
'trending-up': ArrowTrendingUpIcon, // 别名(兼容连字符写法)
download: ArrowDownTrayIcon,
upload: ArrowUpTrayIcon,
// 媒体
play: PlayIcon,
pause: PauseIcon,
stop: StopIcon,
// 其他
refresh: ArrowPathIcon,
arrowPath: ArrowPathIcon, // 别名
loading: ArrowPathIcon,
undo: ArrowUturnLeftIcon,
redo: ArrowUturnRightIcon,
menu: Bars3Icon
}
// 获取图标组件
const iconComponent = computed(() => {
return iconMap[props.name] || InformationCircleIcon
})
// 尺寸类
const sizeClass = computed(() => {
return `icon-${props.size}`
})
// 图标样式
const iconStyle = computed(() => {
return {
color: props.color
}
})
</script>
<style lang="scss" scoped>
.app-icon {
display: inline-block;
flex-shrink: 0;
vertical-align: middle;
// 统一图标样式 - 苹果风格
stroke-width: 1.5;
&.icon-xs {
width: 12px;
height: 12px;
}
&.icon-sm {
width: 16px;
height: 16px;
}
&.icon-md {
width: 20px;
height: 20px;
}
&.icon-lg {
width: 24px;
height: 24px;
}
&.icon-xl {
width: 32px;
height: 32px;
}
}
</style>