vue集成svgspriteloader

48次阅读

共计 3518 个字符,预计需要花费 9 分钟才能阅读完成。

主流图标使用方法

  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.js

const 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>

正文完
 0