Icon 图标
介绍
移动端图标由 dh-design 维护,默认使用从 MasterGo 图标页整理出的图标清单,并支持继续接入设计规范导出的 SVG。业务侧统一使用 DhIcon,不再依赖 Vant 内置图标。
引入
ts
import { DhIcon } from '@szhn/dh-design-mobile'代码演示
基础用法
<script setup lang="ts">
import { computed } from 'vue'
import {
DhIcon,
dhIconCategories,
dhIconDefinitions,
showToast,
} from '@szhn/dh-design-mobile'
const categoryLabels: Record<string, string> = {
basic: '基础类',
business: '商务类',
communication: '通讯类',
device: '设备类',
direction: '方向类',
editor: '编辑类',
education: '教育类',
file: '文件类',
media: '影音类',
other: '其他类',
user: '用户类',
warning: '警告类',
weather: '天气类',
}
const groupedIcons = computed(() => dhIconCategories.map(category => ({
category,
label: categoryLabels[category] || category,
icons: dhIconDefinitions.filter(icon => icon.category === category),
})))
const demoIconName = computed(() => (
dhIconDefinitions.find(icon => icon.name === 'check')?.name
|| dhIconDefinitions.find(icon => icon.name === 'check-line')?.name
|| dhIconDefinitions[0]?.name
))
function copyToClipboard(text: string) {
const textarea = document.createElement('textarea')
textarea.value = text
textarea.setAttribute('readonly', '')
textarea.style.position = 'absolute'
textarea.style.left = '-9999px'
document.body.appendChild(textarea)
textarea.select()
document.execCommand('copy')
document.body.removeChild(textarea)
}
function copy(iconName: string) {
const tag = `<dh-icon name="${iconName}" />`
copyToClipboard(tag)
showToast({
type: 'success',
duration: 1500,
className: 'demo-icon-notify',
message: `复制成功:${tag}`,
})
}
</script>
<template>
<div class="demo-icon">
<demo-block title="基础用法">
<div class="demo-icon__usage">
<dh-icon
v-if="demoIconName"
:name="demoIconName"
size="32"
color="#1677ff"
/>
<span v-else>暂无图标,请先导入 SVG 并运行生成命令</span>
</div>
</demo-block>
<demo-block title="图标集合">
<div v-if="groupedIcons.length" class="demo-icon__groups">
<section
v-for="group in groupedIcons"
:key="group.category"
class="demo-icon__group"
>
<h3>{{ group.label }} <span>{{ group.icons.length }}</span></h3>
<button
v-for="icon in group.icons"
:key="icon.name"
class="demo-icon__item"
type="button"
@click="copy(icon.name)"
>
<dh-icon :name="icon.name" size="28" />
<span>{{ icon.name }}</span>
</button>
</section>
</div>
<div v-else class="demo-icon__empty">
将 MasterGo 导出的 SVG 放入图标源目录后,运行生成命令,本页会自动展示图标集合。
</div>
</demo-block>
</div>
</template>
<style lang="less">
.demo-icon {
&-notify {
font-size: 13px;
}
&__usage,
&__empty {
padding: 16px;
color: var(--van-text-color-2);
font-size: 14px;
line-height: 22px;
background: var(--van-background-2);
}
&__groups {
padding: 8px 12px 20px;
background: var(--van-background-2);
}
&__group {
margin-top: 16px;
h3 {
display: flex;
margin: 0 0 10px;
color: var(--van-text-color);
font-size: 14px;
font-weight: 600;
line-height: 20px;
align-items: center;
gap: 6px;
span {
color: var(--van-text-color-3);
font-size: 12px;
font-weight: 400;
}
}
}
&__item {
display: inline-flex;
width: 25%;
min-height: 86px;
padding: 10px 4px;
color: var(--van-text-color);
text-align: center;
background: transparent;
border: 0;
cursor: pointer;
align-items: center;
justify-content: center;
flex-direction: column;
gap: 8px;
span {
display: block;
width: 100%;
color: var(--van-text-color-2);
font-size: 11px;
line-height: 15px;
overflow-wrap: anywhere;
}
&:active {
background-color: var(--van-active-color);
}
}
}
</style>批量制作图标
- 默认运行
pnpm sync:mobile-icons会按 MasterGo 图标页清单生成图标。 - 如果 MasterGo 后续有定制图标,将 SVG 放入
packages/dh-design-mobile/src/icons/source,可以按分类建立子目录。 - 在项目根目录运行
pnpm sync:mobile-icons -- --include-src,即可把本地 SVG 一起生成进来。 - 打开本页确认图标名称和显示效果。
图标命名会自动转成小写短横线格式,例如 Search 会变成 search,arrow_left 会变成 arrow-left。如果导出的名称重复,脚本会自动加上分类前缀或序号,避免冲突。
API
Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| name | 图标名称 | string | - |
| size | 图标大小,不带单位时默认使用 px | number | string | 1em |
| color | 图标颜色 | string | currentColor |
| title | 图标标题 | string | - |
| aria-label | 无障碍名称 | string | - |
| decorative | 是否作为装饰图标 | boolean | true |
类型定义
ts
import type { DhIconName, DhIconDefinition } from '@szhn/dh-design-mobile'