1、通过 https://www.iconfont.cn 下载资源,引入iconfont.js
文件
- icon/index.js
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon' // svg component
import '@/icons/iconFonts/iconfont.js'
Vue.component('svg-icon', SvgIcon)
- scgIcon组件
<template>
<svg class="icon" aria-hidden="true" v-on="$listeners">
<use xlink:href="#icon-user" />
</svg>
</template>
<script>
export default {
name: 'svgIcon',
props: {
iconClass: {
type: String,
required: true,
},
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
},
},
}
</script>
<style lang="less">
.icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
- 使用
<svg-icon icon-class="user"></svg-icon>
2、使用 svg-sprite
接下来我们就要自己来制作 svg-sprite
了。这里要使用到 svg-sprite-loader 这个神器了, 它是一个 webpack loader ,可以将多个 svg 打包成 svg-sprite
。
我们来介绍如何在 vue-cli
的基础上进行改造,加入 svg-sprite-loader
。
我们发现vue-cli
默认情况下会使用 url-loader
对svg进行处理,会将它放在/img
目录下,所以这时候我们引入svg-sprite-loader
会引发一些冲突。
//默认`vue-cli` 对svg做的处理,正则匹配后缀名为.svg的文件,匹配成功之后使用 url-loader 进行处理。
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
}
解决方案有两种,最简单的就是你可以将 test 的 svg 去掉,这样就不会对svg做处理了,当然这样做是很不友善的。
- 你不能保证你所有的 svg 都是用来当做 icon的,有些真的可能只是用来当做图片资源的。
- 不能确保你使用的一些第三方类库会使用到 svg。
所以最安全合理的做法是使用 webpack 的 exclude 和 include ,让svg-sprite-loader
只处理你指定文件夹下面的 svg,url-loaer
只处理除此文件夹之外的所以 svg,这样就完美解决了之前冲突的问题。 代码如下
// set svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
这样配置好了,只要引入svg之后填写类名就可以了
import '@/src/icons/qq.svg; //引入图标
<svg><use xlink:href="#qq" /></svg> //使用图标
- 自动导入
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
requireAll(req)