Vue2 项目里咋灵活用 icon?这些方案帮你挑
做Vue2项目时,想给界面加图标总犯难?选啥方式、咋集成、咋适配不同场景…一堆问题冒出来,其实Vue2里用icon有不少成熟路子,从简单到灵活都有选项,今天就把常见方案拆明白,帮你选到适合自己项目的。
用阿里 iconfont(符号库)咋在Vue2里落地?
先看最常用的阿里 iconfont 符号库玩法,第一步得去 iconfont 官网挑图标,把要用的加到项目里,生成在线链接或者下载代码包,要是选 symbol 方式(现在官网推荐,支持多色图标),生成后会得到一段 js 链接或者本地 js 文件。
接下来在 Vue2 项目里,得把这个 iconfont 的资源引入,比如在 index.html
里用 script 标签引入在线链接,像这样:
<script src="//at.alicdn.com/t/c/font_xxxx.js"></script>
本段代码来自 https://www.codeqd.com/post/20250620900.html
要是怕在线链接不稳定,也能把下载的 js 文件放到项目的 assets
文件夹里,然后在 main.js
里引入:
import './assets/iconfont.js';
本段代码来自 https://www.codeqd.com/post/20250620900.html
这一步是让页面能识别 icon 的符号,相当于给所有图标办了“身份证”。
然后得写个通用的 Icon 组件,让其他地方能方便调用,比如新建个 IconFont.vue
:
<template>
<svg :class="svgClass" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
export default {
name: 'IconFont',
props: {
iconClass: { // 图标在 iconfont 里的命名
type: String,
required: true
},
className: { // 额外的 class,用来调样式
type: String,
default: ''
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`; // 对应 symbol 的 id
},
svgClass() {
return this.className ? `icon ${this.className}` : 'icon';
}
}
}
</script>
<style scoped>
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor; /* 继承父元素颜色,改颜色只需要改父元素 color */
overflow: hidden;
}
</style>
这样在其他组件里用的时候,就跟拼积木似的:
<IconFont icon-class="search" class-name="icon-large" />
好处是图标能自动继承父元素的颜色,改大小只需要调 font-size
,兼容性也不错,但有个小缺点:要是项目里图标更新了,得重新去 iconfont 生成代码,再替换到项目里,不然新图标不显示,这点得记着。
自己封装 SVG Icon 组件,Vue2里咋玩?
要是项目里图标多,还想每个 svg 能自定义颜色、大小,自己封装 SVG 组件更灵活,毕竟 SVG 是矢量图,放大缩小不会糊,颜色也能随便改,适合对图标质感要求高的场景。
第一步,先建个 SvgIcon.vue
组件:
<template>
<svg :class="svgClass" :width="size" :height="size" :fill="color" aria-hidden="true">
<use :xlink:href="`#icon-${name}`"></use>
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
name: { // 对应 svg 文件的命名(不带后缀)
type: String,
required: true
},
size: { // 图标大小,支持数字或字符串
type: [String, Number],
default: 16
},
color: { // 图标颜色,默认继承父元素
type: String,
default: 'currentColor'
},
className: { // 额外 class
type: String,
default: ''
}
},
computed: {
svgClass() {
return this.className ? `svg-icon ${this.className}` : 'svg-icon';
}
}
}
</script>
接下来得让 webpack 能批量处理 svg 文件,这里得用到 require.context
和 svg-sprite-loader
(需要先安装这个 loader),咱在 src 里建个 icons
文件夹,里面再建个 svg
子文件夹,把所有 svg 图标丢进去,然后在 icons
里建个 index.js
,负责注册组件和导入 svg:
import Vue from 'vue';
import SvgIcon from '@/components/SvgIcon'; // 假设组件在 components 文件夹
Vue.component('SvgIcon', SvgIcon); // 全局注册组件
const req = require.context('./svg', false, /\.svg$/); // 自动导入 svg 文件夹下的所有 .svg 文件
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req); // 执行导入
本段代码来自 https://www.codeqd.com/post/20250620900.html
最后在 main.js
里引入这个 index.js
:
import './icons'; // 这样所有 svg 就被自动处理成 symbol 了
本段代码来自 https://www.codeqd.com/post/20250620900.html
现在用的时候就很丝滑:
<svg-icon name="user" size="24" color="#ff0000" />
这种方式好处贼多:改图标直接换 svg 文件就行,颜色大小想咋调咋调;还能利用 webpack 自动导入,不用手动一个个加,但缺点也有——得配置 svg-sprite-loader
,新手可能得花点时间折腾 webpack 配置,不过现在很多 Vue2 脚手架(vue-cli)已经能方便配置 loader,不算啥大问题。
借助 Element UI 这类 UI 库的 icon,能满足需求吗?
要是你项目用了 Element UI,直接用它的 Icon 组件最省事,不用额外找资源,咱先在 main.js
里全局注册 Element UI:
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
本段代码来自 https://www.codeqd.com/post/20250620900.html
然后在组件里直接用,比如加个编辑图标:
<el-icon><edit /></el-icon>
Element UI 自带的图标不算多,但胜在和 UI 库风格统一,按钮、导航栏这些组件里用起来毫无违和感,要是项目追求快速迭代,不需要特别个性化的图标,这方法能省超多时间。
不过缺点也明显:自定义性弱,比如想改图标颜色,得自己写样式覆盖 .el-icon
的 color
;改大小得调 font-size
,而且要是项目没用到 Element UI,为了几个图标引入整个 UI 库,有点得不偿失,所以得看项目技术栈选。
纯 CSS 画 icon,Vue2里适合啥场景?
还有种极简玩法——纯 CSS 画 icon,适合就几个简单图标,不想引入第三方库、不想折腾配置的情况,比如画个加号图标,用伪元素和 transform 就能搞:
<template>
<div class="plus-icon"></div>
</template>
<style scoped>
.plus-icon {
width: 20px;
height: 20px;
position: relative;
background: #ff0000;
}
.plus-icon::before, .plus-icon::after {
content: '';
position: absolute;
background: #fff;
}
.plus-icon::before {
left: 50%;
top: 4px;
width: 2px;
height: 12px;
transform: translateX(-50%);
}
.plus-icon::after {
top: 50%;
left: 4px;
width: 12px;
height: 2px;
transform: translateY(-50%);
}
</style>
这种方式优点很明显:完全自定义,没有任何额外依赖,打包体积小到可以忽略,但缺点也致命——复杂图标根本画不动!比如想画个卡通形象或者带渐变的图标,纯 CSS 根本搞不定,而且维护起来一堆伪元素,后期改需求得一个个调样式,头大得很,所以这种方法只适合按钮上的小箭头、加减号这类超简单图标,项目里图标多的话千万别用。
第三方 icon 组件库(如 vue-awesome)咋整合?
要是你想要图标库丰富度,比如几百个常用图标随便挑,那可以试试 vue-awesome 这类基于 Font Awesome 的库,先安装:
npm install vue-awesome font-awesome --save
然后在 main.js
里引入并注册:
import Vue from 'vue';
import Icon from 'vue-awesome/components/Icon';
import 'font-awesome/css/font-awesome.min.css'; // 引入 Font Awesome 的样式
Vue.component('v-icon', Icon); // 全局注册为 v-icon 组件
本段代码来自 https://www.codeqd.com/post/20250620900.html
用的时候直接写:
<v-icon name="coffee" /> <!-- 咖啡图标 -->
Font Awesome 的图标库很全,文档也详细,组件化用着方便,vue-awesome 支持按需加载,避免引入整个库导致打包体积过大,但缺点是 Font Awesome 的图标风格比较固定,偏扁平化,要是项目需要个性化很强的图标,得自己额外添加,灵活性不如 SVG 组件。
不同场景选不同方案,组合着用更高效
Vue2 里用 icon 没有绝对的“最好方案”,得看项目需求:
- 追求简单快捷、兼容性好 → 选 iconfont 符号库 或者 Element UI 自带 icon;
- 想要高度自定义、矢量可改、图标多 → 自己封装 SVG 组件;
- 极简项目、只有几个小图标 → 纯 CSS 硬画;
- 图标库丰富度优先、不想自己找图标 → 选 vue-awesome 这类第三方库;
实际开发中,很多项目会 组合着用:基础通用图标用 iconfont,个性化图标用 SVG 组件,快速原型开发用 Element UI icon,把这些方案吃透,不管是后台管理系统还是前端展示页,图标这块都能玩得转~下次项目里遇到图标需求,不用再犯难,按场景选方案就行!
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。