Skip to content

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>

批量制作图标

  1. 默认运行 pnpm sync:mobile-icons 会按 MasterGo 图标页清单生成图标。
  2. 如果 MasterGo 后续有定制图标,将 SVG 放入 packages/dh-design-mobile/src/icons/source,可以按分类建立子目录。
  3. 在项目根目录运行 pnpm sync:mobile-icons -- --include-src,即可把本地 SVG 一起生成进来。
  4. 打开本页确认图标名称和显示效果。

图标命名会自动转成小写短横线格式,例如 Search 会变成 searcharrow_left 会变成 arrow-left。如果导出的名称重复,脚本会自动加上分类前缀或序号,避免冲突。

API

Props

参数说明类型默认值
name图标名称string-
size图标大小,不带单位时默认使用 pxnumber | string1em
color图标颜色stringcurrentColor
title图标标题string-
aria-label无障碍名称string-
decorative是否作为装饰图标booleantrue

类型定义

ts
import type { DhIconName, DhIconDefinition } from '@szhn/dh-design-mobile'