- 前端
- UI组件
- 移动开发
- 小程序
【免费下载链接】wot-design-uni
一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。
wd-icon是 wot-design-uni 组件库中承担全局图标展示的基础组件,它基于字体图标(iconfont)方案实现,一套组件即可同时支持内置图标名、第三方字体图标和图片链接三种用法。本文以官方文档 Icon 组件文档 为主线,结合组件源码 wd-icon.vue、属性定义 types.ts 和样式实现 index.scss,讲清楚每个属性的底层行为、自定义图标的接入方式,以及测试用例如何验证这些行为。
组件定位与字体加载机制
wd-icon本质上是一个"字体图标渲染器":它本身不内置任何图形资源,而是依赖@font-face声明的字体文件,把name映射成::before伪元素上的 Unicode 字符。
在 index.scss 中可以看到双份字体声明:
@font-face { font-family: 'wd-icons'; src: url('https://at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.woff2?t=1696817709651') format('woff2'), url('https://at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.woff?t=1696817709651') format('woff'), url('https://at.alicdn.com/t/c/font_4245058_s5cpwl25n7o.ttf?t=1696817709651') format('truetype'); } /* #ifdef APP-PLUS || H5 */ @font-face { font-family: 'wd-icons'; src: url('./wd-icons.ttf') format('truetype'); } /* #endif */这里体现了 uni-app 的条件编译思想:默认走远程 CDN 字体(体积小的 woff2/woff 优先,ttf 兜底),而在APP-PLUS等无法稳定加载远程字体的端上,切换到组件目录内的本地字体文件 wd-icons.ttf。
根节点的样式约束同样在 index.scss 中定义:
@include b(icon) { display: inline-block; font-family: 'wd-icons' !important; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; &::before { display: inline-block; } @include m(image) { width: 1em; height: 1em; } @include e(image) { width: 100%; height: 100%; } }几个关键细节:
font-family: 'wd-icons' !important保证图标字形不受父级字体覆盖;display: inline-block使图标可以像行内元素一样参与文本排版,同时又能接受width/height;1em的宽高单位意味着图片图标会跟随font-size(即size属性)自动缩放,字体图标与图片图标在尺寸行为上天然统一;- 字体内每个图标对应一条
.wd-icon-xxx:before { content: "\exxx"; }规则,例如.wd-icon-add的字符码就在同一文件的规则列表中(如.wd-icon-check:before对应\e64e,.wd-icon-close:before对应\e64d)。
因此"找一个图标名"的正确方式是查看样式文件中的类名,或者直接使用文档站内的图标列表页——它对应源码 Icon 演示页,其中内置了约 300 个图标名的完整清单,并支持按关键字搜索、点击复制<wd-icon name="xxx" size="22px"></wd-icon>代码片段。
基本用法
通过name属性设置要使用的图标:
<wd-icon name="add-circle"></wd-icon>从源码看,name是必填的字符串属性,在 types.ts 中由makeRequiredProp(String)定义:
/** * 使用的图标名字,可以使用链接图片 */ name: makeRequiredProp(String),组件渲染时的根节点 class 拼接逻辑在 wd-icon.vue:
const rootClass = computed(() => { const prefix = props.classPrefix return `${prefix} ${props.customClass} ${isImage.value ? 'wd-icon--image' : prefix + '-' + props.name}` })也就是说,name="add-circle"最终生成的 DOM 类名是wd-icon wd-icon-add-circle(外加可选的custom-class),而.wd-icon-add-circle:before这条 CSS 规则负责把具体的字形字符注入::before伪元素。测试用例 wd-icon.test.ts 验证了这一行为:
const wrapper = mount(WdIcon, { props: { name: 'add' } }) expect(wrapper.classes()).toContain('wd-icon') expect(wrapper.classes()).toContain('wd-icon-add')图标颜色
设置color属性即可自定义颜色:
<wd-icon name="add-circle" color="#0083ff"></wd-icon>颜色被直接写入根节点的内联样式(见 wd-icon.vue):
const rootStyle = computed(() => { const style: CSSProperties = {} if (props.color) { style['color'] = props.color } if (props.size) { style['font-size'] = addUnit(props.size) } return `${objToStyle(style)} ${props.customStyle}` })由于字体图标通过color渲染字符,任何 CSS 颜色值(red、rgb(255,0,0)、rgba(...)、变量等)都可以使用。不设置color时,图标会继承父元素颜色——这也是官方文档中color默认值标注为inherit的原因。这一特性使wd-icon天然适配 wot-design-uni 的暗黑模式:父级文字色变化时,图标颜色自动跟随,无需单独配置。
测试用例同时覆盖了颜色属性传递与多种颜色取值(见 wd-icon.test.ts),并验证了color、size、customStyle三者组合后都会出现在根节点 style 中(wd-icon.test.ts):
const style = wrapper.attributes('style') expect(style).toContain('color: red') expect(style).toContain('font-size: 20px') expect(style).toContain('margin: 8px')图标大小
设置size属性调整尺寸:
<wd-icon name="add-circle" size="20px"></wd-icon> <wd-icon name="add-circle" size="25px"></wd-icon> <wd-icon name="add-circle" size="30px"></wd-icon>size的类型定义是numericProp,即同时接受Number和String(见 props.ts 中的export const numericProp = [Number, String])。当传入纯数字时,组件会通过 util.ts 中的addUnit自动补上px:
export function addUnit(num: number | string) { return Number.isNaN(Number(num)) ? `${num}` : `${num}px` }所以size="20"、:size="20"和size="20px"效果一致;而size="1.5em"这类带单位的字符串会原样透传,适合做随字号缩放的响应式图标。测试用例对两种取值都做了断言(wd-icon.test.ts):像素字符串断言font-size: 20px,数字20断言自动补全为font-size: 20px。
自定义图标
当内置图标不满足业务需要时,wd-icon提供两条扩展路径:引入第三方字体图标库,或直接使用图片。
方式一:自定义字体图标库(class-prefix)
完整流程分三步:
- 准备自己的 iconfont 字体与 CSS。假设在 iconfont 平台生成了项目字体(示例字体族名为
fish),得到如下 CSS(仓库中自带的示例文件即为该结构,见 src/iconfont/index.css):
/* 路径 src/iconfont/index.css */ @font-face { font-family: "fish"; src: url('//at.alicdn.com/t/c/font_4626013_vwpx4thmin.woff2?t=1721314121733') format('woff2'), url('//at.alicdn.com/t/c/font_4626013_vwpx4thmin.woff?t=1721314121733') format('woff'), url('//at.alicdn.com/t/c/font_4626013_vwpx4thmin.ttf?t=1721314121733') format('truetype'); } .fish { font-family: "fish" !important; font-size: 16px; font-style: normal; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } .fish-kehuishouwu:before { content: "\e627"; }- 全局引入该 CSS,让字体和类名规则生效:
<!-- app.vue --> <style> @import '@/iconfont/index.css'; </style>- 通过
class-prefix指向自己的字体族名,name使用去掉前缀后的类名后半段:
<!-- 通过 class-prefix 指定类名为 fish --> <wd-icon class-prefix="fish" name="kehuishouwu" />原理上,classPrefix(模板属性class-prefix,默认值'wd-icon')会被拼接成`${prefix}-${name}`,最终生成fish fish-kehuishouwu这类类名,正好命中第 1 步中.fish-kehuishouwu:before的字形定义。组件测试也覆盖了这一拼接逻辑(wd-icon.test.ts):
const wrapper = mount(WdIcon, { props: { name: 'add', classPrefix: 'custom-prefix' } }) expect(wrapper.classes()).toContain('custom-prefix') expect(wrapper.classes()).toContain('custom-prefix-add')需要注意的约束:
class-prefix的值必须是 CSS 中真实存在的字体族类名前缀(如fish),组件本身不会校验该前缀是否存在;- 自定义字体的 CSS 必须全局引入,否则
::before字形不生效; - 组件默认声明
styleIsolation: 'shared'与addGlobalClass: true(见 wd-icon.vue),小程序端外部样式类才能正确注入根节点。
方式二:图片图标
把name设置为图片 URL 即可直接渲染图片图标。组件会自动检测:只要name中包含/就判定为图片。该判定逻辑在 wd-icon.vue:
const isImage = computed(() => { return isDef(props.name) && props.name.includes('/') })<wd-icon name="https://example.com/icon.png"></wd-icon>命中图片模式后,模板会渲染image标签并附加wd-icon--image修饰类(见 wd-icon.vue):
<template> <view @click="handleClick" :class="rootClass" :style="rootStyle"> <image v-if="isImage" class="wd-icon__image" :src="name"></image> </view> </template>配合前文1em的 CSS 规则,图片会随size/font-size等比缩放,视觉表现与字体图标保持一致。测试用例对http://、https://以及data:base64 三类 URL 均做了验证(wd-icon.test.ts),断言根节点带有wd-icon--image类、内部存在image元素且src与传入值一致。
由includes('/')的判定规则还可以推断一个边界行为:本地不含斜杠的短路径不会触发图片模式,建议使用完整的https://、http://、data:或包含路径分隔符的地址。
API 参考
Attributes
| 参数 | 说明 | 类型 | 可选值 | 默认值 | 最低版本 |
|---|---|---|---|---|---|
| name | 图标名称或图片链接 | string | - | - | - |
| color | 图标的颜色 | string | - | inherit | - |
| size | 图标的字体大小 | string | number | - | inherit | - |
| classPrefix | 类名前缀,用于使用自定义图标 | string | - | 'wd-icon' | 0.1.27 |
| custom-style | 根节点样式 | string | - | - | - |
属性定义与源码一一对应:name必填,color为可选字符串,size为numericProp(number/string 双类型),classPrefix默认'wd-icon'(见 types.ts)。custom-style与custom-class则来自组件库统一的baseProps(见 props.ts),所有 wot-design-uni 组件通用。
Events
| 事件名称 | 说明 | 参数 |
|---|---|---|
| click | 点击图标时触发 | event: Event |
事件由 wd-icon.vue 中绑定的handleClick发出:
function handleClick(event: any) { emit('click', event) }典型用途是把图标当按钮使用,例如折叠面板的展开箭头。库内部组件本身就是这种用法,如 wd-search 中渲染的<wd-icon name="search" />、wd-collapse-item 中通过custom-class控制箭头旋转变态的<wd-icon name="arrow-down" />。
外部样式类
| 类名 | 说明 |
|---|---|
| custom-class | 根节点自定义样式类,可覆盖图标颜色、大小等 |
组件声明了addGlobalClass: true与styleIsolation: 'shared',因此小程序端也可以从外部页面/组件的样式中直接命中.wd-icon内部节点(演示页中即通过custom-class="icon-item-class"配合:deep(.icon-item-class)来统一设置图标颜色,见 Icon 演示页)。
实践建议与常见排查
- 图标不显示:优先检查
name是否与样式文件中的类名完全一致(含-1、-filled、-thin等后缀,如search1与search是两个不同图标);自定义字体场景再检查全局 CSS 是否引入、class-prefix是否与@font-face的font-family一致。 - 颜色不生效:内联
color优先级最高;若发现颜色"漏"了,多半是外层!important规则覆盖,可改用custom-class配合更高优先级的类名。 - 尺寸与排版:图标是
inline-block且默认垂直居中对齐,混排文字时若出现基线偏差,可给图标设置vertical-align或使用custom-style;图片图标用size控制即可,无需单独设置宽高。 - 暗黑模式:不传
color时图标继承父级文字颜色,主题切换会自动生效,建议优先依赖继承而非硬编码颜色。 - 完整图标清单:以 index.scss 中的
.wd-icon-*:before规则或 Icon 演示页 的icons数组为准,两者当前保持一致。
小结
wd-icon用不到百行的模板与脚本(wd-icon.vue)实现了"字体图标 + 图片图标"的统一抽象:name负责选择字形或图片(以/判定),color/size通过内联样式直接映射到 CSS 属性,class-prefix打开第三方字体库的接入通道。理解rootClass/rootStyle两个计算属性的拼接规则后,无论是排查图标不显示、扩展自有图标字体,还是在业务组件中复用箭头、搜索等语义图标,都能快速定位到对应行为。组件的完整行为契约还可以对照 wd-icon 测试用例 逐条验证。
- 前端
- UI组件
- 移动开发
- 小程序
【免费下载链接】wot-design-uni
一个基于Vue3+TS开发的uni-app组件库,提供70+高质量组件,支持暗黑模式、国际化和自定义主题。
相关推荐
wot-design-uni 图标组件(wd-icon)完全指南:内置字体图标、图片图标与自定义 iconfont 的接入实践
wot design uni 图标组件(wd icon)完全指南:内置字体图标、图片图标与自定义 iconfont 的接入实践 导读 wd icon 是 wot
前端UI组件移动开发小程序Varlet Icon 组件完全指南:从字体图标、图片模式到切换动画与自定义图标库的实现原理
Varlet Icon 组件完全指南:从字体图标、图片模式到切换动画与自定义图标库的实现原理 本篇指南基于 Varlet(基于 Material Design
UI组件前端ant-design-blazor 图标组件 Icon 完全指南:从内置图标到 iconfont.cn 自定义图标
ant design blazor 图标组件 Icon 完全指南:从内置图标到 iconfont.cn 自定义图标 ant design blazor 的 Ic
UI组件前端
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考