Skip to content

Icon 图标 ​

通过统一的 name 调用内置图标,适合按钮、输入框、反馈提示和业务自定义图标。

何时使用 ​

  • 需要在组件中展示装饰性图形、状态图形或操作图形。
  • 希望通过统一的尺寸、颜色、旋转和加载动画控制图标。
  • 业务侧需要注册少量自定义 SVG,并以同一种方式调用。

基础用法 ​

vue
<template>
  <x-icon name="x" />
  <x-icon name="check" />
  <x-icon name="search" />
  <x-icon name="loading" />
</template>

图标清单 ​

只展示每种图形的推荐名称,旧名仍可搜索和使用。点击复制推荐写法,避免在同一图形的多个名字间反复选择。

59 / 59
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>

推荐名称与旧名 ​

推荐名称兼容旧名
xclose
chevron-left / right / up / downleft / right / up / down
circle-check / circle-x / circle-alert / circle-minuscheck-circle / close-circle / alert-circle / minus-circle
infoinfo-circle
loader-circleloading-circle
pencil / lock-open / ellipsisedit / unlock / more-horizontal
chevrons-left / chevrons-rightdouble-left / double-right
circle-question-markquestion-circle / circle-question
eye-off / clockeye-invisible / clock-circle
rotate-ccw / rotate-cwrotate-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 ​

参数类型默认值说明
nameIconName | stringundefined图标名称,内置名称有类型提示,自定义名称通过 addIcon 注册
sizenumber | stringundefined图标大小,数字单位为 px
colorstringundefined图标颜色,默认继承文本色
rotatenumberundefined顺时针旋转角度
spinbooleanfalse是否展示旋转动画
titlestringundefined辅助说明,会作为可访问名称使用
ariaLabelstringundefined图标可访问名称
strokeWidthnumber | stringundefined线性图标描边宽度,Lucide 默认 2,Finicon 按来源默认值;实心图标不受影响

方法 ​

方法说明
addIcon(name, icon)注册自定义图标
removeIcon(name)移除已注册图标
hasIcon(name)判断图标是否已注册
searchPublicIcons(keyword)按推荐名和兼容旧名搜索,返回去重的推荐名称

按需导入 ​

ts
import { Icon, addIcon } from 'x-next';

通用图标默认来自 Lucide,随包开箱即用。扩展图标源按需引入,不注册时不占用体积: