转 在 Vue-Cli 中使用 Svg 做 Icon

之前都是用的image sprite或者使用的 Font Awesome这类的开源库
现在咱们已经走进了现代浏览器的年代(ie9+),可以玩点新鲜的东西了,svg

svg 有几个好处:

  • 矢量图,不失真
  • 可以受CSS样式影响,就像一个文本
  • http请求低了

相关阅读: 未来必热:SVG Sprite技术介绍

而对我来说最直观的好处就是可以让设计师给你出一个 svg,而不是自己眼都挑花了去找一个合适的图标:)

做一个 svg-icon 组件

在 vue-cli 生成的 vue 脚手架中添加组件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// path: @/components/SvgIcon/index.vue
<template>
<svg class="svg-icon" aria-hidden="true">
<use :xlink:href="iconName"></use>
</svg>
</template>

<script>
export default {
name: 'icon-svg',
props: {
iconClass: {
type: String,
required: true
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`
}
}
}
</script>

<style>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>

作者:花裤衩
链接:https://juejin.im/post/59bb864b5188257e7a427c09
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

使用:

1
2
3
4
5
6
7
8
9
10
11
12
13
//引入svg组件
import IconSvg from '@/components/IconSvg'

//全局注册icon-svg
Vue.component('icon-svg', IconSvg)

//在代码中使用
<icon-svg icon-class="password" />

作者:花裤衩
链接:https://juejin.im/post/59bb864b5188257e7a427c09
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

现在组件有了,svg 去哪里搞?

使用 svg-sprite-loader

这个工具可以把多个 svg 打包成 svg-sprite

为了把 icon 使用的 svg 和其他地方使用的 svg 区分开,我们需要对webpack.base.conf.js中的内容
重新设置一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//path: app-project/build/webpack.base.conf.js
...
// [新增]当引用图标 svg 的时候引入指定目录下的文件
{
test: /\.svg$/,
loader: 'svg-sprite-loader',
include: [resolve('src/icons')],
options: {
symbolId: 'icon-[name]'
}
},
// [修改]这里 exclude 来忽略常规的 svg 引入
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
exclude: [resolve('src/icons')], // 这一步必不可少
options: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
...

接下来需要使用 webpack 的require.context函数

require.context(“./test”, false, /.test.js$/);这行代码就会去 test 文件夹(不包含子目录)下面的找所有文件名以 .test.js 结尾的文件能被 require 的文件。更直白的说就是 我们可以通过正则匹配引入相应的文件模块。

为了拆卸方便就把这些都放在了icons目录下

1
2
3
4
5
6
7
8
9
10
11
12
// path: app-project/src/icons.index.js
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg组件

// 全局注册组件
Vue.component('svg-icon', SvgIcon)

// 定义一个加载目录的函数
const requireAll = requireContext => requireContext.keys().map(requireContext)
const req = require.context('./svg', false, /\.svg$/)
// 加载目录下的所有 svg 文件
requireAll(req)

然后只需要在 main.js 文件中引入这个组件就可以了

1
2
3
4
// path: app-project/src/main.js
...
import './icons' // 引入图标文件
...

具体代码可以参考 这个地址链接

压缩 svg 内容

这里推荐一个比较好用的工具: svgo SVG精简压缩工具svgo简介和初体验

最后

这是我抄的 花裤衩的 手摸手,带你优雅的使用 icon,观摩别人的代码给自己带来了很多收获

这个博客有个赞赏功能,不试一下吗?