需要安装@iconify/vue
Antdsign的图标可以直接拿来使用,如下
javascript
<Icon icon="ant-design:menu-outlined"></Icon>
import { Icon } from "@iconify/vue";
自定义图标需要获取图标的Svg的Path,然后自定义注册,记得在main.ts引入,如下
javascript
import { addIcon } from '@iconify/vue';
addIcon('icon3-huanzheguanli', {
width: 1024,
height: 1024,
body: `<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<path fill="#0070f3" d="
m35,0 v35 h-35 v30 h35 v35 h30 v-35 h35 v-30 h-35 v-35 z
"></path>
</svg>`
});
图标选择器效果如下

完整组件代码如下
javascript
<template>
<div class="icon-picker">
<div class="icon-picker-trigger" @click="showDialog = true">
<slot name="trigger">
<div class="trigger-button">
<Icon v-if="modelValue" :icon="modelValue" class="selected-icon" />
<span v-else class="placeholder">
<Icon icon="ant-design:appstore-outlined" class="placeholder-icon" />
选择图标
</span>
</div>
</slot>
</div>
<el-dialog
v-model="showDialog"
width="900px"
:close-on-click-modal="true"
:close-on-press-escape="true"
:show-close="true"
title="选择图标"
class="icon-picker-dialog"
>
<div class="dialog-content">
<!-- 搜索框 -->
<div class="search-box">
<Icon icon="ant-design:search-outlined" class="search-icon" />
<input
v-model="searchText"
type="text"
placeholder="搜索图标名称..."
class="search-input"
@input="handleSearch"
/>
<button v-if="searchText" class="clear-btn" @click="clearSearch">
<Icon icon="ant-design:close-circle-outlined" />
</button>
</div>
<!-- 图标列表 -->
<div class="icon-list-container">
<div v-if="filteredIcons.length === 0" class="empty-state">
<Icon icon="ant-design:inbox-outlined" class="empty-icon" />
<p>未找到匹配的图标</p>
<p class="empty-tip">试试其他关键词</p>
</div>
<div v-else class="icon-list">
<div
v-for="icon in filteredIcons"
:key="icon.id"
:class="['icon-item', { active: isSelected(icon) }]"
@click="selectIcon(icon)"
:title="icon.name"
>
<div class="icon-wrapper">
<Icon :icon="icon.id" class="icon-display" />
</div>
<div class="icon-name">{{ icon.label }}</div>
</div>
</div>
</div>
</div>
</el-dialog>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { Icon } from '@iconify/vue'
const props = defineProps({
modelValue: {
type: String,
default: ''
}
})
const emit = defineEmits(['update:modelValue', 'change'])
const showDialog = ref(false)
const searchText = ref('')
// Ant Design 图标集合(常用图标,去重)
const antDesignIcons = [
// 基础图标
{ id: 'ant-design:home-outlined', name: 'home', label: '首页' },
{ id: 'ant-design:user-outlined', name: 'user', label: '用户' },
{ id: 'ant-design:team-outlined', name: 'team', label: '团队' },
{ id: 'ant-design:setting-outlined', name: 'setting', label: '设置' },
{ id: 'ant-design:search-outlined', name: 'search', label: '搜索' },
{ id: 'ant-design:menu-outlined', name: 'menu', label: '菜单' },
{ id: 'ant-design:appstore-outlined', name: 'appstore', label: '应用' },
{ id: 'ant-design:close-outlined', name: 'close', label: '关闭' },
{ id: 'ant-design:check-outlined', name: 'check', label: '确认' },
{ id: 'ant-design:plus-outlined', name: 'plus', label: '添加' },
{ id: 'ant-design:minus-outlined', name: 'minus', label: '减少' },
{ id: 'ant-design:delete-outlined', name: 'delete', label: '删除' },
{ id: 'ant-design:edit-outlined', name: 'edit', label: '编辑' },
{ id: 'ant-design:save-outlined', name: 'save', label: '保存' },
{ id: 'ant-design:download-outlined', name: 'download', label: '下载' },
{ id: 'ant-design:upload-outlined', name: 'upload', label: '上传' },
{ id: 'ant-design:folder-outlined', name: 'folder', label: '文件夹' },
{ id: 'ant-design:folder-open-outlined', name: 'folder-open', label: '打开文件夹' },
{ id: 'ant-design:file-outlined', name: 'file', label: '文件' },
{ id: 'ant-design:file-text-outlined', name: 'file-text', label: '文本文件' },
{ id: 'ant-design:file-image-outlined', name: 'file-image', label: '图片文件' },
{ id: 'ant-design:picture-outlined', name: 'picture', label: '照片' },
{ id: 'ant-design:video-camera-outlined', name: 'video-camera', label: '视频' },
{ id: 'ant-design:mail-outlined', name: 'mail', label: '邮件' },
{ id: 'ant-design:phone-outlined', name: 'phone', label: '电话' },
{ id: 'ant-design:calendar-outlined', name: 'calendar', label: '日历' },
{ id: 'ant-design:clock-circle-outlined', name: 'clock-circle', label: '时钟' },
{ id: 'ant-design:bell-outlined', name: 'bell', label: '通知' },
{ id: 'ant-design:star-outlined', name: 'star', label: '收藏' },
{ id: 'ant-design:heart-outlined', name: 'heart', label: '喜欢' },
{ id: 'ant-design:like-outlined', name: 'like', label: '点赞' },
{ id: 'ant-design:share-alt-outlined', name: 'share-alt', label: '分享' },
{ id: 'ant-design:printer-outlined', name: 'printer', label: '打印' },
{ id: 'ant-design:copy-outlined', name: 'copy', label: '复制' },
{ id: 'ant-design:scissor-outlined', name: 'scissor', label: '剪切' },
{ id: 'ant-design:redo-outlined', name: 'redo', label: '重做' },
{ id: 'ant-design:undo-outlined', name: 'undo', label: '撤销' },
// 方向图标
{ id: 'ant-design:arrow-up-outlined', name: 'arrow-up', label: '向上' },
{ id: 'ant-design:arrow-down-outlined', name: 'arrow-down', label: '向下' },
{ id: 'ant-design:arrow-left-outlined', name: 'arrow-left', label: '向左' },
{ id: 'ant-design:arrow-right-outlined', name: 'arrow-right', label: '向右' },
{ id: 'ant-design:up-outlined', name: 'up', label: '上' },
{ id: 'ant-design:down-outlined', name: 'down', label: '下' },
{ id: 'ant-design:left-outlined', name: 'left', label: '左' },
{ id: 'ant-design:right-outlined', name: 'right', label: '右' },
{ id: 'ant-design:double-left-outlined', name: 'double-left', label: '双左' },
{ id: 'ant-design:double-right-outlined', name: 'double-right', label: '双右' },
// 状态图标
{ id: 'ant-design:check-circle-outlined', name: 'check-circle', label: '成功' },
{ id: 'ant-design:close-circle-outlined', name: 'close-circle', label: '错误' },
{ id: 'ant-design:exclamation-circle-outlined', name: 'exclamation-circle', label: '警告' },
{ id: 'ant-design:info-circle-outlined', name: 'info-circle', label: '信息' },
{ id: 'ant-design:question-circle-outlined', name: 'question-circle', label: '疑问' },
{ id: 'ant-design:stop-outlined', name: 'stop', label: '停止' },
{ id: 'ant-design:warning-outlined', name: 'warning', label: '警告' },
// 数据图标
{ id: 'ant-design:bar-chart-outlined', name: 'bar-chart', label: '柱状图' },
{ id: 'ant-design:line-chart-outlined', name: 'line-chart', label: '折线图' },
{ id: 'ant-design:pie-chart-outlined', name: 'pie-chart', label: '饼图' },
{ id: 'ant-design:area-chart-outlined', name: 'area-chart', label: '面积图' },
{ id: 'ant-design:table-outlined', name: 'table', label: '表格' },
{ id: 'ant-design:database-outlined', name: 'database', label: '数据库' },
{ id: 'ant-design:cloud-outlined', name: 'cloud', label: '云' },
{ id: 'ant-design:cloud-upload-outlined', name: 'cloud-upload', label: '云上传' },
{ id: 'ant-design:cloud-download-outlined', name: 'cloud-download', label: '云下载' },
// 操作图标
{ id: 'ant-design:reload-outlined', name: 'reload', label: '刷新' },
{ id: 'ant-design:sync-outlined', name: 'sync', label: '同步' },
{ id: 'ant-design:poweroff-outlined', name: 'poweroff', label: '电源' },
{ id: 'ant-design:lock-outlined', name: 'lock', label: '锁定' },
{ id: 'ant-design:unlock-outlined', name: 'unlock', label: '解锁' },
{ id: 'ant-design:eye-outlined', name: 'eye', label: '查看' },
{ id: 'ant-design:eye-invisible-outlined', name: 'eye-invisible', label: '隐藏' },
{ id: 'ant-design:filter-outlined', name: 'filter', label: '筛选' },
{ id: 'ant-design:sort-ascending-outlined', name: 'sort-ascending', label: '升序' },
{ id: 'ant-design:sort-descending-outlined', name: 'sort-descending', label: '降序' },
// 其他常用图标
{ id: 'ant-design:shopping-cart-outlined', name: 'shopping-cart', label: '购物车' },
{ id: 'ant-design:shopping-outlined', name: 'shopping', label: '购物' },
{ id: 'ant-design:gift-outlined', name: 'gift', label: '礼物' },
{ id: 'ant-design:tag-outlined', name: 'tag', label: '标签' },
{ id: 'ant-design:tags-outlined', name: 'tags', label: '标签组' },
{ id: 'ant-design:book-outlined', name: 'book', label: '书籍' },
{ id: 'ant-design:read-outlined', name: 'read', label: '阅读' },
{ id: 'ant-design:file-search-outlined', name: 'file-search', label: '文件搜索' },
{ id: 'ant-design:folder-add-outlined', name: 'folder-add', label: '新建文件夹' },
{ id: 'ant-design:inbox-outlined', name: 'inbox', label: '收件箱' },
{ id: 'ant-design:message-outlined', name: 'message', label: '消息' },
{ id: 'ant-design:notification-outlined', name: 'notification', label: '通知' },
{ id: 'ant-design:customer-service-outlined', name: 'customer-service', label: '客服' },
{ id: 'ant-design:question-outlined', name: 'question', label: '帮助' },
{ id: 'ant-design:tool-outlined', name: 'tool', label: '工具' },
{ id: 'ant-design:api-outlined', name: 'api', label: 'API' },
{ id: 'ant-design:code-outlined', name: 'code', label: '代码' },
{ id: 'ant-design:bug-outlined', name: 'bug', label: 'Bug' },
{ id: 'ant-design:experiment-outlined', name: 'experiment', label: '实验' },
{ id: 'ant-design:thunderbolt-outlined', name: 'thunderbolt', label: '闪电' },
{ id: 'ant-design:fire-outlined', name: 'fire', label: '火焰' },
{ id: 'ant-design:rocket-outlined', name: 'rocket', label: '火箭' },
{ id: 'ant-design:global-outlined', name: 'global', label: '全球' },
{ id: 'ant-design:compass-outlined', name: 'compass', label: '指南针' },
{ id: 'ant-design:environment-outlined', name: 'environment', label: '位置' },
{ id: 'ant-design:car-outlined', name: 'car', label: '汽车' },
{ id: 'ant-design:medicine-box-outlined', name: 'medicine-box', label: '医疗' },
{ id: 'ant-design:bank-outlined', name: 'bank', label: '银行' },
{ id: 'ant-design:shop-outlined', name: 'shop', label: '商店' },
{ id: 'ant-design:build-outlined', name: 'build', label: '建筑' },
{ id: 'ant-design:audit-outlined', name: 'audit', label: '审核' },
{ id: 'ant-design:security-scan-outlined', name: 'security-scan', label: '安全扫描' },
{ id: 'ant-design:safety-outlined', name: 'safety', label: '安全' },
{ id: 'ant-design:key-outlined', name: 'key', label: '钥匙' },
{ id: 'ant-design:wallet-outlined', name: 'wallet', label: '钱包' },
{ id: 'ant-design:credit-card-outlined', name: 'credit-card', label: '信用卡' },
{ id: 'ant-design:pay-circle-outlined', name: 'pay-circle', label: '支付' },
{ id: 'ant-design:transaction-outlined', name: 'transaction', label: '交易' },
{ id: 'ant-design:account-book-outlined', name: 'account-book', label: '账本' },
{ id: 'ant-design:calculator-outlined', name: 'calculator', label: '计算器' },
{ id: 'ant-design:fund-outlined', name: 'fund', label: '基金' },
{ id: 'ant-design:stock-outlined', name: 'stock', label: '股票' },
{ id: 'ant-design:gold-outlined', name: 'gold', label: '黄金' },
{ id: 'ant-design:trophy-outlined', name: 'trophy', label: '奖杯' },
{ id: 'ant-design:crown-outlined', name: 'crown', label: '皇冠' },
{ id: 'ant-design:bulb-outlined', name: 'bulb', label: '灯泡' },
{ id: 'ant-design:highlight-outlined', name: 'highlight', label: '高亮' },
{ id: 'ant-design:pushpin-outlined', name: 'pushpin', label: '图钉' },
{ id: 'ant-design:flag-outlined', name: 'flag', label: '旗帜' },
{ id: 'ant-design:link-outlined', name: 'link', label: '链接' },
{ id: 'ant-design:disconnect-outlined', name: 'disconnect', label: '断开' },
{ id: 'ant-design:wifi-outlined', name: 'wifi', label: 'WiFi' },
{ id: 'ant-design:usb-outlined', name: 'usb', label: 'USB' },
{ id: 'ant-design:desktop-outlined', name: 'desktop', label: '桌面' },
{ id: 'ant-design:laptop-outlined', name: 'laptop', label: '笔记本' },
{ id: 'ant-design:tablet-outlined', name: 'tablet', label: '平板' },
{ id: 'ant-design:mobile-outlined', name: 'mobile', label: '手机' },
{ id: 'ant-design:scan-outlined', name: 'scan', label: '扫描' },
{ id: 'ant-design:qrcode-outlined', name: 'qrcode', label: '二维码' },
{ id: 'ant-design:barcode-outlined', name: 'barcode', label: '条形码' },
{ id: 'ant-design:camera-outlined', name: 'camera', label: '相机' },
{ id: 'ant-design:video-camera-add-outlined', name: 'video-camera-add', label: '添加视频' },
{ id: 'ant-design:audio-outlined', name: 'audio', label: '音频' },
{ id: 'ant-design:contacts-outlined', name: 'contacts', label: '联系人' },
{ id: 'ant-design:usergroup-add-outlined', name: 'usergroup-add', label: '添加用户组' },
{ id: 'ant-design:user-add-outlined', name: 'user-add', label: '添加用户' },
{ id: 'ant-design:user-delete-outlined', name: 'user-delete', label: '删除用户' },
{ id: 'ant-design:user-switch-outlined', name: 'user-switch', label: '切换用户' },
{ id: 'ant-design:logout-outlined', name: 'logout', label: '退出' },
{ id: 'ant-design:login-outlined', name: 'login', label: '登录' },
{ id: 'ant-design:safety-certificate-outlined', name: 'safety-certificate', label: '安全证书' },
{ id: 'ant-design:idcard-outlined', name: 'idcard', label: '身份证' },
{ id: 'ant-design:verified-outlined', name: 'verified', label: '已验证' },
{ id: 'ant-design:file-protect-outlined', name: 'file-protect', label: '文件保护' },
{ id: 'ant-design:file-excel-outlined', name: 'file-excel', label: 'Excel' },
{ id: 'ant-design:file-pdf-outlined', name: 'file-pdf', label: 'PDF' },
{ id: 'ant-design:file-word-outlined', name: 'file-word', label: 'Word' },
{ id: 'ant-design:file-ppt-outlined', name: 'file-ppt', label: 'PPT' },
{ id: 'ant-design:file-zip-outlined', name: 'file-zip', label: 'ZIP' },
{ id: 'ant-design:file-markdown-outlined', name: 'file-markdown', label: 'Markdown' },
{ id: 'ant-design:file-unknown-outlined', name: 'file-unknown', label: '未知文件' },
{ id: 'ant-design:file-add-outlined', name: 'file-add', label: '新建文件' },
{ id: 'ant-design:file-done-outlined', name: 'file-done', label: '完成文件' },
{ id: 'ant-design:file-exclamation-outlined', name: 'file-exclamation', label: '文件警告' },
{ id: 'ant-design:file-sync-outlined', name: 'file-sync', label: '文件同步' },
{ id: 'ant-design:file-search-outlined', name: 'file-search', label: '文件搜索' },
{ id: 'ant-design:folder-view-outlined', name: 'folder-view', label: '查看文件夹' },
{ id: 'ant-design:play-circle-outlined', name: 'play-circle', label: '播放' },
{ id: 'ant-design:pause-circle-outlined', name: 'pause-circle', label: '暂停' },
{ id: 'ant-design:step-backward-outlined', name: 'step-backward', label: '上一步' },
{ id: 'ant-design:step-forward-outlined', name: 'step-forward', label: '下一步' },
{ id: 'ant-design:fast-backward-outlined', name: 'fast-backward', label: '快退' },
{ id: 'ant-design:fast-forward-outlined', name: 'fast-forward', label: '快进' },
{ id: 'ant-design:shrink-outlined', name: 'shrink', label: '收缩' },
{ id: 'ant-design:arrows-alt-outlined', name: 'arrows-alt', label: '全屏' },
{ id: 'ant-design:fullscreen-outlined', name: 'fullscreen', label: '全屏' },
{ id: 'ant-design:fullscreen-exit-outlined', name: 'fullscreen-exit', label: '退出全屏' },
{ id: 'ant-design:zoom-in-outlined', name: 'zoom-in', label: '放大' },
{ id: 'ant-design:zoom-out-outlined', name: 'zoom-out', label: '缩小' },
{ id: 'ant-design:expand-outlined', name: 'expand', label: '展开' },
{ id: 'ant-design:compress-outlined', name: 'compress', label: '压缩' },
{ id: 'ant-design:enter-outlined', name: 'enter', label: '进入' },
{ id: 'ant-design:export-outlined', name: 'export', label: '导出' },
{ id: 'ant-design:import-outlined', name: 'import', label: '导入' },
{ id: 'ant-design:swap-outlined', name: 'swap', label: '交换' },
{ id: 'ant-design:swap-left-outlined', name: 'swap-left', label: '左交换' },
{ id: 'ant-design:swap-right-outlined', name: 'swap-right', label: '右交换' },
{ id: 'ant-design:retweet-outlined', name: 'retweet', label: '转发' },
{ id: 'ant-design:rollback-outlined', name: 'rollback', label: '回滚' },
{ id: 'ant-design:history-outlined', name: 'history', label: '历史' },
{ id: 'ant-design:schedule-outlined', name: 'schedule', label: '日程' },
{ id: 'ant-design:number-outlined', name: 'number', label: '数字' },
{ id: 'ant-design:font-size-outlined', name: 'font-size', label: '字体大小' },
{ id: 'ant-design:bold-outlined', name: 'bold', label: '粗体' },
{ id: 'ant-design:italic-outlined', name: 'italic', label: '斜体' },
{ id: 'ant-design:underline-outlined', name: 'underline', label: '下划线' },
{ id: 'ant-design:strikethrough-outlined', name: 'strikethrough', label: '删除线' },
{ id: 'ant-design:font-colors-outlined', name: 'font-colors', label: '字体颜色' },
{ id: 'ant-design:bg-colors-outlined', name: 'bg-colors', label: '背景颜色' },
{ id: 'ant-design:align-left-outlined', name: 'align-left', label: '左对齐' },
{ id: 'ant-design:align-center-outlined', name: 'align-center', label: '居中' },
{ id: 'ant-design:align-right-outlined', name: 'align-right', label: '右对齐' },
{ id: 'ant-design:ordered-list-outlined', name: 'ordered-list', label: '有序列表' },
{ id: 'ant-design:unordered-list-outlined', name: 'unordered-list', label: '无序列表' },
{ id: 'ant-design:line-height-outlined', name: 'line-height', label: '行高' },
{ id: 'ant-design:column-width-outlined', name: 'column-width', label: '列宽' },
{ id: 'ant-design:border-outlined', name: 'border', label: '边框' },
{ id: 'ant-design:border-inner-outlined', name: 'border-inner', label: '内边框' },
{ id: 'ant-design:border-outer-outlined', name: 'border-outer', label: '外边框' },
{ id: 'ant-design:border-left-outlined', name: 'border-left', label: '左边框' },
{ id: 'ant-design:border-right-outlined', name: 'border-right', label: '右边框' },
{ id: 'ant-design:border-top-outlined', name: 'border-top', label: '上边框' },
{ id: 'ant-design:border-bottom-outlined', name: 'border-bottom', label: '下边框' },
{ id: 'ant-design:radius-setting-outlined', name: 'radius-setting', label: '圆角设置' },
{ id: 'ant-design:radius-bottomleft-outlined', name: 'radius-bottomleft', label: '左下圆角' },
{ id: 'ant-design:radius-bottomright-outlined', name: 'radius-bottomright', label: '右下圆角' },
{ id: 'ant-design:radius-upleft-outlined', name: 'radius-upleft', label: '左上圆角' },
{ id: 'ant-design:radius-upright-outlined', name: 'radius-upright', label: '右上圆角' },
{ id: 'icon3-shoushuguanli', name: 'shoushuguanli', label: '手术管理' },
]
// 过滤后的图标
const filteredIcons = computed(() => {
if (!searchText.value.trim()) {
return antDesignIcons
}
const keyword = searchText.value.toLowerCase()
return antDesignIcons.filter(icon =>
icon.name.toLowerCase().includes(keyword) ||
icon.label.toLowerCase().includes(keyword) ||
icon.id.toLowerCase().includes(keyword)
)
})
// 判断是否选中
const isSelected = (icon: typeof antDesignIcons[0]) => {
return props.modelValue === icon.id
}
// 选择图标
const selectIcon = (icon: typeof antDesignIcons[0]) => {
emit('update:modelValue', icon.id)
emit('change', icon)
showDialog.value = false
searchText.value = ''
}
// 清除搜索
const clearSearch = () => {
searchText.value = ''
}
// 处理搜索
const handleSearch = () => {
// 搜索逻辑已在 computed 中处理
}
</script>
<style scoped>
.icon-picker {
display: inline-block;
}
.trigger-button {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 8px 16px;
border: 1px solid #dcdfe6;
border-radius: 6px;
background: #fff;
cursor: pointer;
transition: all 0.3s ease;
font-size: 14px;
color: #606266;
}
.trigger-button:hover {
border-color: #409eff;
color: #409eff;
box-shadow: 0 2px 4px rgba(64, 158, 255, 0.1);
}
.selected-icon {
width: 18px;
height: 18px;
color: #409eff;
}
.placeholder {
display: flex;
align-items: center;
gap: 6px;
color: #909399;
}
.placeholder-icon {
width: 16px;
height: 16px;
}
.dialog-content {
display: flex;
flex-direction: column;
height: 600px;
}
.search-box {
position: relative;
padding: 20px;
border-bottom: 1px solid #ebeef5;
flex-shrink: 0;
}
.search-icon {
position: absolute;
left: 32px;
top: 50%;
transform: translateY(-50%);
width: 18px;
height: 18px;
color: #909399;
pointer-events: none;
}
.search-input {
width: 100%;
padding: 10px 40px 10px 40px;
border: 1px solid #dcdfe6;
border-radius: 6px;
font-size: 14px;
outline: none;
transition: all 0.3s ease;
background: #fafafa;
}
.search-input:focus {
border-color: #409eff;
background: #fff;
box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1);
}
.clear-btn {
position: absolute;
right: 32px;
top: 50%;
transform: translateY(-50%);
width: 20px;
height: 20px;
border: none;
background: transparent;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #c0c4cc;
transition: color 0.3s ease;
}
.clear-btn:hover {
color: #909399;
}
.icon-list-container {
flex: 1;
overflow-y: auto;
padding: 20px;
background: #fafafa;
}
.icon-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
gap: 12px;
}
.icon-item {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 20px 12px;
border: 1px solid #ebeef5;
border-radius: 8px;
cursor: pointer;
transition: all 0.3s ease;
background: #fff;
position: relative;
overflow: hidden;
}
.icon-item::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: linear-gradient(135deg, rgba(64, 158, 255, 0.05) 0%, rgba(64, 158, 255, 0.02) 100%);
opacity: 0;
transition: opacity 0.3s ease;
}
.icon-item:hover {
border-color: #409eff;
background: #ecf5ff;
transform: translateY(-4px);
box-shadow: 0 4px 12px rgba(64, 158, 255, 0.15);
}
.icon-item:hover::before {
opacity: 1;
}
.icon-item.active {
border-color: #409eff;
background: linear-gradient(135deg, #ecf5ff 0%, #d9ecff 100%);
box-shadow: 0 2px 8px rgba(64, 158, 255, 0.2);
}
.icon-item.active::before {
opacity: 1;
}
.icon-wrapper {
width: 48px;
height: 48px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 8px;
position: relative;
z-index: 1;
}
.icon-display {
width: 28px;
height: 28px;
color: #606266;
transition: all 0.3s ease;
}
.icon-item:hover .icon-display {
color: #409eff;
transform: scale(1.1);
}
.icon-item.active .icon-display {
color: #409eff;
}
.icon-name {
font-size: 12px;
color: #606266;
text-align: center;
word-break: break-all;
line-height: 1.4;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
position: relative;
z-index: 1;
transition: color 0.3s ease;
}
.icon-item:hover .icon-name {
color: #409eff;
font-weight: 500;
}
.icon-item.active .icon-name {
color: #409eff;
font-weight: 500;
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 80px 20px;
color: #909399;
}
.empty-icon {
width: 64px;
height: 64px;
color: #c0c4cc;
margin-bottom: 16px;
}
.empty-state p {
margin: 8px 0;
font-size: 14px;
}
.empty-tip {
font-size: 12px;
color: #c0c4cc;
}
/* 滚动条样式 */
.icon-list-container::-webkit-scrollbar {
width: 8px;
}
.icon-list-container::-webkit-scrollbar-track {
background: #f5f7fa;
border-radius: 4px;
}
.icon-list-container::-webkit-scrollbar-thumb {
background: #dcdfe6;
border-radius: 4px;
transition: background 0.3s ease;
}
.icon-list-container::-webkit-scrollbar-thumb:hover {
background: #c0c4cc;
}
/* Dialog 样式优化 */
:deep(.el-dialog) {
border-radius: 12px;
overflow: hidden;
}
:deep(.el-dialog__header) {
padding: 20px 24px;
border-bottom: 1px solid #ebeef5;
background: #fff;
}
:deep(.el-dialog__title) {
font-size: 18px;
font-weight: 600;
color: #303133;
}
:deep(.el-dialog__body) {
padding: 0;
}
</style>