Appearance
Icon 图标
通过统一的 name 调用内置图标,适合按钮、输入框、反馈提示和业务自定义图标。
何时使用
- 需要在组件中展示装饰性图形、状态图形或操作图形。
- 希望通过统一的尺寸、颜色、旋转和加载动画控制图标。
- 业务侧需要注册少量自定义 SVG,并以同一种方式调用。
基础用法
vue
<template>
<x-icon name="x" />
<x-icon name="check" />
<x-icon name="search" />
<x-icon name="loading" />
</template>图标清单
只展示每种图形的推荐名称,旧名仍可搜索和使用。点击复制推荐写法,避免在同一图形的多个名字间反复选择。
vue
<template>
<div
class="icon-browser"
:style="{
'--icon-color': iconColor,
'--icon-size': `${iconSize}px`,
}"
>
<section class="icon-customizer">
<label>
<span>Color</span>
<span>
<input v-model="iconColor" type="color" />
<code>{{ iconColor }}</code>
</span>
</label>
<label>
<span>Size</span>
<em>{{ iconSize }}px</em>
<input v-model.number="iconSize" type="range" min="16" max="44" step="2" />
</label>
<label>
<span>Stroke</span>
<em>{{ iconStrokeWidth }}</em>
<input v-model.number="iconStrokeWidth" type="range" min="1" max="3" step="0.25" />
</label>
</section>
<input v-model="keyword" placeholder="搜索图标名称" />
<div class="icon-grid">
<button
v-for="name in filteredIcons"
:key="name"
:title="getIconCode(name)"
@click="copyIconName(name)"
>
<x-icon
:name="name"
:size="iconSize"
:stroke-width="iconStrokeWidth"
:spin="name === 'loader-circle'"
/>
<span>{{ name }}</span>
</button>
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue';
import { Message, searchPublicIcons } from 'x-next';
const keyword = ref('');
const iconColor = ref('#000000');
const iconSize = ref(24);
const iconStrokeWidth = ref(2);
const filteredIcons = computed(() => searchPublicIcons(keyword.value));
const getIconCode = (name: string) =>
name === 'loader-circle' ? `<x-icon name="${name}" spin />` : `<x-icon name="${name}" />`;
const copyIconName = async (name: string) => {
const code = getIconCode(name);
try {
if (!navigator.clipboard?.writeText) throw new Error('Clipboard unavailable');
await navigator.clipboard.writeText(code);
Message.success(`已复制 ${code}`);
} catch {
Message.warning(`复制失败,请手动复制:${code}`);
}
};
</script>推荐名称与旧名
| 推荐名称 | 兼容旧名 |
|---|---|
x | close |
chevron-left / right / up / down | left / right / up / down |
circle-check / circle-x / circle-alert / circle-minus | check-circle / close-circle / alert-circle / minus-circle |
info | info-circle |
loader-circle | loading-circle |
pencil / lock-open / ellipsis | edit / unlock / more-horizontal |
chevrons-left / chevrons-right | double-left / double-right |
circle-question-mark | question-circle / circle-question |
eye-off / clock | eye-invisible / clock-circle |
rotate-ccw / rotate-cw | rotate-left / rotate-right |
arrow-* 是带箭杆的方向箭头,chevron-* 是单折角,chevrons-* 是双折角。三个系列用途不同,分别保留。
publicIconNames 保留历史清单;新建图标选择器可使用 canonicalIconNames,需要兼容搜索时使用 searchPublicIcons(keyword)。旧名和推荐名始终引用同一份 SVG。
尺寸和颜色
vue
<template>
<x-icon name="search" :size="14" />
<x-icon name="search" :size="20" />
<x-icon name="search" size="1.75em" />
<x-icon name="circle-check" :size="22" color="var(--x-color-success-6)" />
<x-icon name="circle-x" :size="22" color="var(--x-color-danger-6)" />
</template>描边宽度
vue
<template>
<x-icon name="search" :size="28" :stroke-width="1" />
<x-icon name="search" :size="28" :stroke-width="2" />
<x-icon name="search" :size="28" :stroke-width="3" />
<x-icon name="circle-question-mark" :size="28" :stroke-width="1.5" />
</template>Lucide 线性图标默认描边为 2,可通过 stroke-width 调整。动态图标 loading 使用自身动画规格;实心图形和品牌图标不会因描边参数变粗。
旋转和加载
vue
<template>
<x-icon name="chevron-right" :rotate="90" />
<x-icon name="chevron-right" :rotate="180" />
<x-icon name="loading" />
<x-icon name="loader-circle" spin />
<x-icon name="loading" :size="22" color="var(--x-color-primary-6)" />
</template>loading 是 X-Next 自带的变长圆弧,自动播放动画;loader-circle 是固定开口圆环,配合 spin 旋转。两种加载效果分别保留;系统减少动效时均显示静态图形。
图标按钮
vue
<template>
<x-button shape="circle" aria-label="搜索" title="搜索">
<x-icon name="search" />
</x-button>
<x-button type="outline" shape="circle" aria-label="下载" title="下载">
<x-icon name="download" />
</x-button>
<x-button type="primary">
<template #icon>
<x-icon name="plus" />
</template>
新建
</x-button>
<x-button type="text" status="danger" aria-label="删除">
<template #icon>
<x-icon name="trash" />
</template>
删除
</x-button>
<x-button type="text" shape="circle" aria-label="关闭" title="关闭">
<x-icon name="x" />
</x-button>
</template>可点击图标应由按钮或其他可交互控件承载,并提供可访问名称。纯装饰性图标默认会设置 aria-hidden="true"。
自定义图标
vue
<script setup lang="ts">
import { addIcon } from 'x-next';
import diamondSvg from './diamond.svg?raw';
addIcon('demo-diamond', diamondSvg);
</script>
<template>
<x-icon name="demo-diamond" :size="22" color="var(--x-color-primary-6)" />
</template>addIcon 支持本地可信 SVG 字符串。?raw 是 Vite 的文件导入语法,表示把 diamond.svg 的文件内容作为字符串导入;如果不加 ?raw,通常拿到的是打包后的图片 URL,不能直接注册成图标。不要把用户输入或远程接口返回的 SVG 直接传入 addIcon。
API
Props
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
name | IconName | string | undefined | 图标名称,内置名称有类型提示,自定义名称通过 addIcon 注册 |
size | number | string | undefined | 图标大小,数字单位为 px |
color | string | undefined | 图标颜色,默认继承文本色 |
rotate | number | undefined | 顺时针旋转角度 |
spin | boolean | false | 是否展示旋转动画 |
title | string | undefined | 辅助说明,会作为可访问名称使用 |
ariaLabel | string | undefined | 图标可访问名称 |
strokeWidth | number | string | undefined | 线性图标描边宽度,Lucide 默认 2,Finicon 按来源默认值;实心图标不受影响 |
方法
| 方法 | 说明 |
|---|---|
addIcon(name, icon) | 注册自定义图标 |
removeIcon(name) | 移除已注册图标 |
hasIcon(name) | 判断图标是否已注册 |
searchPublicIcons(keyword) | 按推荐名和兼容旧名搜索,返回去重的推荐名称 |
按需导入
ts
import { Icon, addIcon } from 'x-next';通用图标默认来自 Lucide,随包开箱即用。扩展图标源按需引入,不注册时不占用体积:
- 金融业务图标见 Finicon 金融图标。
- 三风格通用图标与品牌 Logo 见 Boxicons 图标。