参考链接:https://juejin.im/post/59bb864b5188257e7a427c09
使用 iconfont
阿里开源图库 https://www.iconfont.cn/
使用方法 https://www.iconfont.cn/help/detail?spm=a313x.7781069.1998910419.d8d11a391&helptype=code
下载代码到本地(也可以使用在线链接)打开 demo_index.html 使用说明,有三种使用方式 unicode font-class symbol
unicode 方式: 3 这样,不直观,语意不明确,不支持多色图标
font-class 方式: 使用 class 定义,有语意,需要注意命名空间的问题,也是不支持多色图标
symbol 方式:使用 svg 不用再去请求 woff|eot|ttf| 这些字体库,且缩放不会失真,支持更加复杂的图标
symbol 方式使用步骤:
第一步:引入项目下面生成的 symbol 代码:
<script src="./iconfont.js"></script>
|
或通过 import 导入
第二步:加入通用 CSS 代码:
.icon { width: 1em; height: 1em; vertical-align: -0.15em; fill: currentColor; overflow: hidden; }
|
第三步:挑选相应图标并获取类名,应用于页面:
<svg class="icon" aria-hidden="true"><use xlink:href="#icon-xxx"></use></svg>
|
symbol 其实使用了 SVG Sprite 技术, 所有的 svg-sprite 都是通过 iconfont 的 iconfont.js 生成的,所以:
所有图标 icon 都很不直观,完全不知道哪个图标名对应什么图标,每次增删改图标,或者添加一些自定义的 svg 图标,只能将其也上传到 iconfont 和原有的图标放在一个项目库中,之后再重新下载,将整体 js 文件一起替换,而且也做不到按需加载
导出的 svg 包含大量的无用信息,例如编辑器源信息、注释等。通常包含其它一些不会影响渲染结果或可以移除的内容
vue cli3 项目使用 svg-sprite-loader 打包 svg
vue cli3 默认使用 file-loader 处理 svg:
{ test: /\.(svg)(\?.*)?$/, use: [ { loader: 'file-loader', options: { name: 'static/img/[name].[hash:8].[ext]' } } ] }
|
并路径指定为在 img 文件夹下,但我们的 svg 并不在 img 文件夹,而且 svg-sprite-loader 已经自带了 file-loader 的功能,所以,我们可以在我们自定义的 vue.config.js 文件下将 rule (svg) 清除:
module.exports = { chainWebpack: config => { config.module.rule('svg').uses.clear() } }
|
或者添加忽略,然后加上自定义的 svg rule,最后的配置如下:
config.module .rule('svg') .exclude.add(path.resolve(__dirname, 'src/icons')) .end()
config.module .rule('svg-sprite-loader') .include.add(path.resolve(__dirname, 'src/icons')) .end() .test(/\.svg$/) .use('svg-sprite') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]' }) .end()
|
之后可以通过如下方式使用
<svg><use xlink:href="#icon-qq" /></svg>
|
使用缺点:需要手动导入图标
自动导入
使用 webpack 的 require.context api
require.context 语法
require.context(directory, (useSubdirectories = false), (regExp = /^\.\//))
require.context('./test', false, /\.test\.js$/)
|
自动引入 @/icons 下面所有的图标
const requireComponent = require.context('../../components', false)
requireComponent.keys().forEach(filename => { const componentConfig = requireComponent(filename)
const componentName = filename .split('/') .pop() .replace(/\.\w+$/, '')
Vue.component( componentName, componentConfig.default || componentConfig ) })
|
const requireAll = requireContext => requireContext.keys().map(requireContext) const req = require.context('@/icons', false) requireAll(req)
|
之后直接将图标放入 @/icons 文件夹下就可以直接使用了,删改图标同理
优化 svg
删除无用信息 svgo
阿里云导出的 svg 是带有默认的 fill 的,导致图标不能继承父级元素的颜色,可以通过删除默认 fill 解决
安装
npm i svgo svgo-loader -D
|
config.module .rule('svg-sprite-loader') .include.add(path.resolve(__dirname, 'src/icons')) .use('svgo-loader') .loader('svgo-loader') .tap(options => { options = { plugins: [ { removeXMLNS: true }, { convertStyleToAttrs: true } ] } return options })
|
也可以在图标管理中 我的项目 批量操作 批量去色 将默认颜色去除, 之后可以通过 css 自定义颜色