Code前端首页关于Code前端联系我们

Vue2 项目里咋灵活用 icon?这些方案帮你挑

terry 2周前 (06-18) 阅读数 36 #Vue
文章标签 Vue2;icon方案

做Vue2项目时,想给界面加图标总犯难?选啥方式、咋集成、咋适配不同场景…一堆问题冒出来,其实Vue2里用icon有不少成熟路子,从简单到灵活都有选项,今天就把常见方案拆明白,帮你选到适合自己项目的。

用阿里 iconfont(符号库)咋在Vue2里落地?

先看最常用的阿里 iconfont 符号库玩法,第一步得去 iconfont 官网挑图标,把要用的加到项目里,生成在线链接或者下载代码包,要是选 symbol 方式(现在官网推荐,支持多色图标),生成后会得到一段 js 链接或者本地 js 文件。

接下来在 Vue2 项目里,得把这个 iconfont 的资源引入,比如在 index.html 里用 script 标签引入在线链接,像这样:

Markup
<script src="//at.alicdn.com/t/c/font_xxxx.js"></script>

本段代码来自 https://www.codeqd.com/post/20250620900.html

要是怕在线链接不稳定,也能把下载的 js 文件放到项目的 assets 文件夹里,然后在 main.js 里引入:

JavaScript
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.contextsvg-sprite-loader(需要先安装这个 loader),咱在 src 里建个 icons 文件夹,里面再建个 svg 子文件夹,把所有 svg 图标丢进去,然后在 icons 里建个 index.js,负责注册组件和导入 svg:

JavaScript
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

JavaScript
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:

JavaScript
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-iconcolor;改大小得调 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 的库,先安装:

Bash
npm install vue-awesome font-awesome --save

然后在 main.js 里引入并注册:

JavaScript
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前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门