---
title: Icon 图标
description: 以类名、内置名或资源渲染的图标
category: Basic
status: beta
since: 0.3.4
tags: [icon, glyph, visual]
syncStatus: reviewed
verified: true
---

## 用法

### 类名图标

:::TuffCodeBlock{lang="vue"}
---
code: |
  <template>
    <!-- Remix Icon -->
    <i class="i-ri-home-line" />
    <i class="i-ri-search-line" />
    <i class="i-ri-settings-3-line" />
    <!-- Carbon -->
    <i class="i-carbon-user" />
    <i class="i-carbon-folder" />

    <!-- Simple Icons (品牌) -->
    <i class="i-simple-icons-github" />
    <i class="i-simple-icons-visualstudiocode" />
  </template>
---
:::

### TuffIcon
`TuffIcon`（别名 `TxIcon`）的 `name` 接受类名或内置名，`icon` 接受结构化来源。

:::TuffCodeBlock{lang="vue"}
---
code: |
  <template>
    <TuffIcon name="i-ri-home-line" />
    <TuffIcon name="chevron-down" />
    <TuffIcon :icon="{ type: 'emoji', value: '🚀' }" />
    <TuffIcon :icon="{ type: 'url', value: '/app.svg', colorful: true }" />
  </template>
---
:::

### TuffIcons 常量
`@talex-touch/utils` 提供预定义的图标常量。

:::TuffCodeBlock{lang="ts"}
---
code: |
  import { TuffIcons, AppIcons } from '@talex-touch/utils'

  // 通用 UI 图标
  TuffIcons.Home // 'i-ri-home-line'
  TuffIcons.Search // 'i-ri-search-line'
  TuffIcons.Settings // 'i-ri-settings-3-line'

  // 应用品牌图标
  AppIcons.VSCode // 'i-simple-icons-visualstudiocode'
  AppIcons.GitHub // 'i-simple-icons-github'
---
:::

| 分类 | 常量 | 类名 |
|------|------|------|
| 导航 | `TuffIcons.Home` | `i-ri-home-line` |
| | `TuffIcons.Back` | `i-ri-arrow-left-line` |
| | `TuffIcons.Forward` | `i-ri-arrow-right-line` |
| | `TuffIcons.Menu` | `i-ri-menu-line` |
| 操作 | `TuffIcons.Search` | `i-ri-search-line` |
| | `TuffIcons.Add` | `i-ri-add-line` |
| | `TuffIcons.Delete` | `i-ri-delete-bin-line` |
| | `TuffIcons.Edit` | `i-ri-edit-line` |
| | `TuffIcons.Copy` | `i-ri-file-copy-line` |
| | `TuffIcons.Save` | `i-ri-save-line` |
| | `TuffIcons.Download` | `i-ri-download-line` |
| | `TuffIcons.Upload` | `i-ri-upload-line` |
| | `TuffIcons.Refresh` | `i-ri-refresh-line` |
| 状态 | `TuffIcons.Check` | `i-ri-check-line` |
| | `TuffIcons.Close` | `i-ri-close-line` |
| | `TuffIcons.Warning` | `i-ri-error-warning-line` |
| | `TuffIcons.Info` | `i-ri-information-line` |
| | `TuffIcons.Error` | `i-ri-close-circle-line` |
| 文件 | `TuffIcons.File` | `i-ri-file-line` |
| | `TuffIcons.Folder` | `i-ri-folder-line` |
| | `TuffIcons.FileCode` | `i-ri-file-code-line` |
| | `TuffIcons.FileImage` | `i-ri-image-line` |
| 界面元素 | `TuffIcons.Settings` | `i-ri-settings-3-line` |
| | `TuffIcons.User` | `i-ri-user-line` |
| | `TuffIcons.Star` | `i-ri-star-line` |
| | `TuffIcons.Heart` | `i-ri-heart-line` |
| | `TuffIcons.Lock` | `i-ri-lock-line` |
| | `TuffIcons.Eye` | `i-ri-eye-line` |
| 品牌 | `AppIcons.GitHub` | `i-simple-icons-github` |
| | `AppIcons.VSCode` | `i-simple-icons-visualstudiocode` |
| | `AppIcons.Chrome` | `i-simple-icons-googlechrome` |
| | `AppIcons.Discord` | `i-simple-icons-discord` |

### 自定义样式

:::TuffCodeBlock{lang="vue"}
---
code: |
  <template>
    <!-- 尺寸 -->
    <i class="i-ri-home-line text-sm" />
    <i class="i-ri-home-line text-base" />
    <i class="i-ri-home-line text-xl" />
    <i class="i-ri-home-line text-2xl" />

    <!-- 颜色 -->
    <i class="i-ri-star-line text-yellow-500" />
    <i class="i-ri-heart-fill text-red-500" />
    <i class="i-ri-check-circle-fill text-green-500" />

    <!-- 动画 -->
    <i class="i-ri-loader-4-line animate-spin" />
  </template>
---
:::

### 状态角标
`TxStatusIcon` 的 `tone` 在图标右下角叠加状态点。
:::TuffDemoWrapper{demo="IconTxStatusIconDemo" code-lang="vue"}
---
code: |
  <template>
    <TxStatusIcon name="i-carbon-translate" :size="24" tone="success" />
    <TxStatusIcon name="i-carbon-translate" :size="24" tone="warning" />
    <TxStatusIcon name="i-carbon-translate" :size="24" tone="error" />
    <TxStatusIcon name="i-carbon-translate" :size="24" tone="info" />
    <TxStatusIcon name="i-carbon-translate" :size="24" tone="loading" />
  </template>
---
:::

### 操作系统图标
`TxOsIcon` 根据 `platform` 与 `os` 识别平台。
:::TuffDemoWrapper{demo="OsIconOsIconDemo" code-lang="vue"}
---
code: |
  <template>
    <TxOsIcon platform="darwin" os="macOS 15" />
    <TxOsIcon platform="win32" os="Windows 11" />
    <TxOsIcon platform="linux" os="Ubuntu 24.04" />
  </template>
---
:::

### 图标来源

| `type` | 用途 |
|------|------|
| `class` | 图标类名（推荐）。 |
| `emoji` | 轻量强调。 |
| `file` / `url` | 本地或远程图标。 |
| `builtin` | 内置图标：`check`、`chevron-down`、`close`、`search`、`user`、`star`、`star-half`、`info`、`check-circle`、`x-circle`、`alert-triangle`。 |

`colorful` 可写在组件属性上，也可写在 `icon.colorful` 中。

### 最佳实践

- 产品 UI 优先用 UnoCSS 类名（`i-*`），它继承 `currentColor`；需要状态、URL / file 解析或保留原色时再用 `TxIconSource`。
- 只有图标本身承载语义时才设置 `alt`；装饰性图标的语义交给周围文本。
- 单色 SVG 保持 `colorful=false` 以跟随主题色；品牌标识与多色图设置 `colorful=true`。
- 在应用外壳注入一次 `TX_ICON_CONFIG_KEY`，不要逐个图标传 resolver。
- `TxOsIcon` 搭配可见的平台文本，用 CSS 字号调整大小；回退图标只是视觉默认值，不是校验结果。

## API 参考

### TxIcon

#### 属性
::TuffPropsTable
---
rows:
  - name: icon
    type: 'TxIconSource | null'
    default: '-'
    description: '结构化图标来源（type / value），与 name 二选一。'
  - name: name
    type: 'string'
    default: '-'
    description: '类名或内置图标名。'
  - name: size
    type: 'number'
    default: '-'
    description: '尺寸（px）；省略时继承父级字号。'
  - name: colorful
    type: 'boolean'
    default: 'false'
    description: '保留 SVG 原色。'
  - name: alt
    type: 'string'
    default: "''"
    description: '可访问名称，写入 title；也用作兜底图片的 alt。'
  - name: empty
    type: 'string'
    default: "''"
    description: '未解析出图标时显示的兜底图片 URL。'
  - name: urlResolver
    type: "(url: string, type: 'url' | 'file') => string"
    default: '-'
    description: '覆盖 URL / file 路径解析。'
  - name: svgFetcher
    type: '(url: string) => Promise<string>'
    default: '-'
    description: '覆盖 SVG 内容获取。'
---
::

#### 插槽

| 名称 | 参数 | 说明 |
|------|------|------|
| `empty` | - | 替换未解析出图标时的兜底内容。 |

### TxStatusIcon

#### 属性
::TuffPropsTable
---
rows:
  - name: colorful
    type: 'boolean'
    default: 'true'
    description: '保留 SVG 原色；默认 true，与 TxIcon 相反。'
  - name: size
    type: 'number'
    default: '18'
    description: '尺寸（px）；默认 18，TxIcon 则继承父级字号。'
  - name: tone
    type: "'none' | 'loading' | 'warning' | 'success' | 'error' | 'info'"
    default: "'none'"
    description: '右下角的状态点；none 时不显示。'
  - name: indicatorSize
    type: 'number'
    default: '自动'
    description: '状态点尺寸（px）。'
  - name: indicatorOffset
    type: 'number'
    default: '0'
    description: '状态点偏移（px）。'
---
::

`icon`、`name`、`alt`、`empty` 与 `TxIcon` 相同。

### TxOsIcon

#### 属性
::TuffPropsTable
---
rows:
  - name: platform
    type: 'string'
    default: "''"
    description: '平台标识，如 darwin、win32、linux。'
  - name: os
    type: 'string'
    default: "''"
    description: '可读的系统名称，同样参与识别。'
---
::

### classIcon / getIcon

:::TuffCodeBlock{lang="ts"}
---
code: |
  import { classIcon, getIcon } from '@talex-touch/utils'

  const icon = classIcon('i-ri-star-line')
  // { type: 'class', value: 'i-ri-star-line' }

  const searchIcon = getIcon('Search')
  // { type: 'class', value: 'i-ri-search-line' }
---
:::

## 图标集

| 图标集 | 前缀 | 描述 |
|--------|------|------|
| Remix Icon | `i-ri-` | 通用 UI 图标，线条 / 填充风格 |
| Carbon | `i-carbon-` | IBM 设计系统图标 |
| Simple Icons | `i-simple-icons-` | 品牌 / Logo 图标 |

## 图标搜索

在 [Icônes](https://icones.js.org/) 浏览和搜索全部图标。

## 概述

- `name` 以 `i-` 开头时按类名渲染，命中内置名时渲染内置 SVG，其余按类名渲染；类不存在时不显示任何内容。
- `file` 与本地绝对 `url` 经注入的 `fileProtocol` 或 `urlResolver` 转换。
- `colorful=false` 时，能读到内容（data URL 或 `svgFetcher`）的单色 SVG 以 `currentColor` 遮罩渲染；多色或读不到内容的 SVG 渲染原图。
- `icon.status` 为 `loading` 或 `error` 时优先显示对应状态。
- 设置 `alt` 时根节点为 `role="img"` 并带 `title`；未设置时为 `aria-hidden="true"`。
- `TxOsIcon` 将 `platform` 与 `os` 合并转小写，识别 macOS / Windows / Linux，未识别时显示 macOS；SVG 为 `aria-hidden`。

## 技术实现

- `shouldRenderSvgAsMask` 检查 SVG 的绘制颜色是否都是中性色或 `currentColor`，以决定是否走遮罩。
- `TX_ICON_CONFIG_KEY` 注入 `urlResolver`、`svgFetcher` 与 `fileProtocol`。
- 源码：`packages/tuffex/packages/components/src/icon/`。

<TuffDocSourceLink />
