SwIcon

SwIcon 是一个纯粹的尺寸与颜色容器(<span class="sw-icon">),不内嵌任何具体图标。真正的 SVG 内容通过默认 slot 传入。在实际项目中,与 AppIcon 组件配合使用,两层职责分离:

  • AppIcon(业务层):通过 inject-icons 构建脚本将 assets/icons/*.svg 注入到组件中,使用 v-if="name === '图标名'" 决定渲染哪个 SVG,再将其通过 slot 交给 SwIcon。
  • SwIcon(框架层):使用 :deep() 将 SVG 内部的 fill 和 stroke 统一改为 currentColor,实现颜色的 CSS 继承控制。

基础用法

<!-- 业务层推荐用法:通过 AppIcon 使用 inject-icons 注入的图标 -->
<AppIcon name="home" />
<AppIcon name="user" :width="24" color="#3b82f6" />

<!-- 进阶用法:直接向 SwIcon 传入一次性内联 SVG -->
<SwIcon name="custom" :width="32" color="#f59e0b">
  <svg viewBox="0 0 24 24"><path d="..." /></svg>
</SwIcon>

inject-icons 构建流程

在项目根目录执行 pnpm inject-icons,脚本会读取 app/assets/icons/ 下所有 *.svg 文件,自动注入到 AppIcon.vue 组件的 ICONS:START / ICONS:END 标记区间中。

# 将 app/assets/icons/home.svg 注入为 <AppIcon name="home" />
pnpm inject-icons

# 之后即可在任意组件中使用
<AppIcon name="home" />
<AppIcon name="settings" :width="20" color="var(--primary)" />

尺寸与颜色

尺寸与颜色示例

展示 width、height、color prop 的各种用法,以及随父字号缩放的效果。

加载中...

颜色:currentColor 继承 + 显式 token

加载中...

1em 随父字号缩放

加载中...

默认宽高均为 1em,随父元素字号自动缩放,无需额外指定即可与文字等比例排列。颜色默认继承父元素的 color CSS 属性。

Props

名称类型必填默认值说明
namestring—图标标识,原样落到 data-icon 属性上,便于从 DOM / 截图反查是哪个图标。不参与渲染——图标本体由 default slot 提供
widthnumber | string— (CSS fallback 1em)图标宽度,number 自动拼 px。不传则不写内联样式,尺寸由 --sw-icon-width 的 CSS fallback 承担
heightnumber | string'1em'图标高度,number 自动拼 px;
colorstring— (CSS fallback currentColor)图标颜色。同上,不传则无内联样式

Slots

插槽名说明
defaultSVG 内容,一般由 AppIcon 组件注入

颜色继承规则

SwIcon 使用 :deep() 将 SVG 内所有带 fill 或 stroke 属性的元素改为 currentColor,但 fill="none" 和 stroke="none"(透明路径)不会被覆盖。因此只需设置 color prop 或通过 CSS 设置父元素的 color 属性即可控制整个图标颜色。

<!-- 通过父元素 color 控制(继承) -->
<p style="color: #ef4444;">
  <AppIcon name="warning" />  <!-- 自动继承红色 -->
  警告文字
</p>

<!-- 通过 color prop 单独控制(不影响父元素) -->
<AppIcon name="star" color="#f59e0b" />

样式定制 Token

以下 CSS 变量可在业务侧覆盖(fallback 即默认值):

变量默认值说明
--sw-icon-colorcurrentcolor图标颜色。默认继承文字色,见「颜色继承规则」
--sw-icon-height1em图标高度。默认跟随字号
--sw-icon-width1em图标宽度。默认跟随字号

注意事项

  • SwIcon 是图标「容器」,不是图标库 —— 它只管尺寸(1em 跟随字号)与颜色(currentColor),图标内容由 slot 提供。业务侧通常不直接写 SwIcon:项目自有 SVG 写 <AppIcon name="x" />(starter 的 AppIcon 内部就是 SwIcon 的封装),UI 功能图标直接用图标库组件(starter 用 @phosphor-icons/vue,如 <PhX />)——图标库组件自带尺寸 / 颜色 prop,不需要再套 SwIcon。
  • 多色 SVG 会被压平成单色 —— 颜色继承规则把所有 fill / stroke(none 除外)改写为 currentColor,这对单色图标是便利,但品牌 logo 等多色 SVG 放进来会丢掉配色。多色资源改用 SwImage(fit="contain")或直接内联 <svg>。
  • 默认 aria-hidden="true" —— 按「装饰性图标」处理,读屏器会跳过。图标单独承载语义时(纯图标按钮等),需在外层可交互元素上补 aria-label,而不是去掉 aria-hidden。
  • 渲染为 <span> 而非 <i> —— 避免与 iconfont / Font Awesome 等占用 <i> 的库冲突;写 CSS 选择器时按 span.sw-icon 命中。
  • 1em 默认值是 stylelint em 禁用规则的唯一例外 —— framework 全站禁 em 单位(嵌套复合难追踪),SwIcon 的 1em 跟随字号模式是明确豁免项,不要据此在别处用 em。