主流图标使用方法

  1. 雪碧图backgrount定位
  2. img
  3. iconfont
  4. symbol

svg-sprite工作原理

利用svg的symbol元素,将每个icon包括在symbol中,通过use元素使用该symbol。点击查看详细原理

svg-sprite优缺点

优点:

  1. 修改ID就可以改变图标,使用方便。
  2. 页面代码量小,维护成本低。
  3. 图标可改变颜色大小,减少重复图片的加载
  4. 减少图片请求量。

缺点:

  1. 多色、渐变色等无法通过色值改变图标颜色,需要设计师重新设计图标。
  2. 浏览器渲染性能一般。
  3. 浏览器兼容性不佳,支持ie9+,现代浏览器。

工具

1、懒人神器svg-sprite-loader

解决的痛点

根据导入的 svg 文件自动生成 symbol 标签(svg雪碧图)并插入 html。

安装

npm install svg-sprite-loader --save-dev

vue-cli2.0 webpack配置

需要做背景的svg图片处理方法:
将处理svg的loader添加exclude,表示不需要使用改loader处理icon。

// build/webpack.base.conf.js{    test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,    exclude: [resolve('src/assets/icons/svg')],    loader: 'url-loader',    options: {      limit: 10000,      name: utils.assetsPath('img/[name].[hash:7].[ext]')    }}

需要做icon的图片处理方法:
对include中的svg文件进行雪碧图处理。option可以设置symbolID,若不设置则默认id为svg文件名。

// build/webpack.base.conf.js{    test: /\.svg$/,    include: [resolve('src/assets/icons/svg')],    loader: 'svg-sprite-loader',    options: {      symbolId: 'icon-[name]' // 指定symbolId 不指定则默认为svg文件名    }}

vue-cli3.0 webpack配置

webapck 配置自定义,可参考官方demo

// vue.config.jsconst path = require('path')function resolve(dir) {  return path.join(__dirname, './', dir)}module.exports = {  chainWebpack: config => {    config.module      .rule('svg')      .exclude.add(resolve('src/assets/icons'))      .end()    config.module      .rule('icons')      .test(/\.svg$/)      .include.add(resolve('src/assets/icons'))      .end()      .use('svg-sprite-loader')      .loader('svg-sprite-loader')      .options({        symbolId: '[name]'      })  }}

页面中的使用方法

webpack配置完后可以在页面中直接使用。import引入需要使用的icon图标

import './assets/icons/svg/za-icon-supplier.svg'

引入后查看页面是否已经载入symbol标签内容(即svg雪碧图),效果如下:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0" id="__SVG_SPRITE_NODE__">    <symbol xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 20 18" id="icon名">{{省略的icon path}}</symbol></svg>

symbol载入成功后,在template中使用svg标签。xlink的href替换为svg图标的id或者在webpack中自定义的id。

<svg><use xlink:href="#icon-za-icon-supplier" /></svg>

修改图标颜色,大小。

<style type="text/css">    .za-svg-icon {      width: 20px;      height: 20px;      vertical-align: middle;      fill: currentColor;      overflow: hidden;    }</style>

到此为止已经可以正常引入使用图标了。

组件化

目前使用图标需要import引入图标,svg画图,再写公共样式。可以再简化一点,将这些内容放到公共组件内。组件内容如下:

// src/components/SvgIcon.vue<!-- 公共svgicon组件 --><template>  <svg :class="svgClass" aria-hidden="true">    <use :xlink:href="iconName"/>  </svg></template><script>export default {  name: 'SvgIcon',  props: {    iconClass: {      type: String,      required: true    },    className: {      type: String,      default: ''    }  },  computed: {    iconName () {      return `#za-icon-${this.iconClass}`    },    svgClass () {      if (this.className) {        return `za-svg-icon za-icon-${this.iconClass} ` + this.className      } else {        return `za-svg-icon za-icon-${this.iconClass}`      }    }  }}</script><style lang="scss">.za-svg-icon {  width: 20px;  height: 20px;  vertical-align: middle;  fill: currentColor;  overflow: hidden;}</style>

现在使用组件只需要两步。

import './assets/icons/svg/za-icon-supplier.svg'<svg-icon icon-class="supplier"></svg-icon>

自动导入

最后一个问题就是,每次使用图标都需要import。可以使用webpack的 ==require.context== 方法,动态引入icon图标。
具体文档戳这里。

import Vue from 'vue'import SvgIcon from '@/components/SvgIcon.vue'// 统一注册svg-icon组件Vue.component('svg-icon', SvgIcon)// 遍历require.context的返回模块,并导入const requireAll = requireContext => requireContext.keys().map(requireContext)// import所有符合条件的svg 三个参数:文件夹、是否使用子文件夹、正则const req = require.context('@/assets/icons/svg', true, /\.svg$/)requireAll(req)

现在只需要在页面直接使用svg-icon组件,修改icon-class就可以展示icon了。

2、iconfont的symbol使用方式

第一步:拷贝项目下面生成的symbol代码:

// at.alicdn.com/t/font_8d5l8fzk5b87iudi.js

第二步:加入通用css代码(引入一次就行):

<style type="text/css">    .icon {       width: 1em; height: 1em;       vertical-align: -0.15em;       fill: currentColor;       overflow: hidden;    }</style>

第三步:挑选相应图标并获取类名,应用于页面:

<svg class="icon" aria-hidden="true">    <use xlink:href="#icon-xxx"></use></svg>