Vue Cli 3.0发布到现在6个月了,从2.0到3.0的距离就像是Spring到Spring Boot的距离。网上有各种中文的英文的意大利文的介绍,这里就不多啰嗦了。近一段时间的项目,大部分的Icon图标来源于阿里矢量图的图库,但是一旦手痒弄几个别的SVG,比如:
对没错,这篇文章的主题是为了推广一下这位大佬的微博,各位可以感受一下纯粹的CSS加上想象力之后有多么惊心动魄。好了全文结束。
好吧,来处理一下这些帅气的SVG:
<script>
import svgLogo from '@/assets/svg/handsome.svg'
</script>
...
<img :scr=svgLogo />
大概就是这么个意思。代码现场手打,复制绝对报错。这么硬核的代码一看就让人泪牛满面,于是苦心翻找(炫酷google),大概知道了这么个玩意儿:svg-sprite-loader,大概的意思就是把SVG转成了HTML的symbol标签,当然百分之98的人不会关心你到底是symbol还是png,最主要是,引入要优雅,要流畅,要富有艺术气息。
由于VUE CLI3的坐骑Webpack4的配置和Webpack3的配置方式有了很大的区别,所以传统的很多博客教程都扑街了。这里有一篇不错:VUE-cli3使用 svg-sprite-loader。这里为了满足大部分着急解决问题,准备CtrlCV连击直接带走jira的朋友,所以我们进入真正的步骤:
第一步,Vue Create xxx
好好好
npm install svg-sprite-loader -D
这里稍微提一下,如果最后你的npm run serve出现了这种报错:
Can Not Found 什么 Dependence:
svg-baker-runtime/brows-symbol
那么就是伟大的npm又坑了你。我们查看一下svg-sprite-loader的npm,发现其实依赖里是有svg-baker-runtime的,npm本着根本没有下载假装下载了的一贯作风报出来的错,所以有需要的同学手动install一下。
cnpm i -D svg-baker-runtime
cnmp就是快。
第二步,在项目的根目录下建一个vue.config.js
这个文件,其实是CLI3.0之后用来进行webpack用户自定义配置的,你的乱七八糟的各种loader、gzip、插件,要走这里来配置。我们先来贴一个简单的vue.config.js文件:
const path = require('path');
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
baseUrl: "/",
// 输出目录
outputDir: 'dist',
lintOnSave: true,
// 是否为生产环境构建生成 source map?
productionSourceMap: false,
// alias 配置
chainWebpack: (config) => {
config.resolve.alias
.set('@', resolve('src'))
config.module.rules.delete("svg");
config.module
.rule('svg-smart')
.test(/\.svg$/)
.include
.add(resolve('src/assets/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: '[name]'
})
}
}
好了,赶着干活的同学复制完可以走了。我们来简单解释一下这个配置文件的意思:webpack-chain
OKOK,刀先放下。
Webpack4有一个新特征,就是支持链式配置。这个东西解释起来有点像Lombok的@Builder,用一个酷炫的点连接把一堆配置项连起来从而到达不可告人的目的。为了能稍微理解的透彻一点,我们在命令行上敲一个
vue inspect >out.js
去根目录下看看这个out.js,是不是感觉很熟悉?
没用过cli2.0的同学我知道你们不熟悉,先假装熟悉一会儿。
然后我们搜索一下svg
/* config.module.rule('svg') */
{
test: /\.(svg)(\?.*)?$/,
use: [
/* config.module.rule('svg').use('file-loader') */
{
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
]
},
完美的file-loader。
好了,现在来解释一下刚才的那个vue.config.js
rules:理解成一个ID或者一个选择器,例如
config.module.rules.delete("svg");
干掉module下名字叫svg的配置项
test:正则匹配文件名规则。/\.svg$/指匹配所有以.svg结束的文件,其实就是svg后缀的文件。
include:包含的文件目录
exclude:不包含的文件目录
注意一下,这个options里面的symbolId不是匹配项,是添加项规则。比如一个symbolId配置为"icon-[name]",那么当你需要引用一个叫icon-swarm.svg的图标的时候,你需要
<svg>
<use xlink:href="icon-icon-swarm"></use>
</svg>
好了,这个时候已经可以正常使用了。
but,每次使用一个icon的时候
import './assets/svg/icon-swarm.svg'
..
<template>
<svg>
<use xlink:href='#icon-swarm'></use>
</svg>
</template>
注意不要漏掉那个#
好吧我知道你们要啥,选择main.js,加入
// requires and returns all modules that match
const requireAll = requireContext => requireContext.keys().map(requireContext);
// import all svg
const req = require.context('./assets/svg', true, /\.svg$/);
requireAll(req);
如果引用了其他的framework框架,比如element-ui,删掉原来的svg处理可能会导致错误。这种时候修正原来的rules('svg'),exclude你的svg文件夹就可以了