vue-cli3引入svg图标全过程以及遇到的坑
一、讲原理svg-sprite,和css-sprite有点像,就是先把所有的svg图放页面上,但是不现实,用的时候去取。这个时候去MDN补一下知识。Symbol这个不是es6里的那个新增的数据类型,而是SVG中的一个标签https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/symbol官方说法:symbol元素用来定义一个图形...
一、讲原理svg-sprite,和css-sprite有点像,就是先把所有的svg图放页面上,但是不现实,用的时候去取。
这个时候去MDN补一下知识。Symbol这个不是es6里的那个新增的数据类型,而是SVG中的一个标签https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/symbol
官方说法:
symbol
元素用来定义一个图形模板对象,它可以用一个<use>
元素实例化。symbol
元素对图形的作用是在同一文档中多次使用,添加结构和语义。结构丰富的文档可以更生动地呈现出来,类似讲演稿或盲文,从而提升了可访问性。注意,一个symbol
元素本身是不呈现的。只有symbol
元素的实例(亦即,一个引用了symbol
的 <use>
元素)才能呈现。
联系一下我刚才说的svg-sprite你就知道了,就是我们要把我们所有svg的单个放到这个标签里,然后再起个ID,用的时候一找这个id就出来。非常完美。原理还有更有深度的东西可以自己百度去吧。
那我们要用时候不能挨个写标签,挨个放进去吧,那就太麻烦了,所有用这个插件svg-sprite-loader,我们只需要准备下svg图,然后起个好记的名字。然后svg是美工给你的,所以你只需要改名字。。为了就是这个,要不谁用他
npm install svg-sprite-loader --save-dev
接下来在vue.config.js里加这些东西。上代码
先找到这个位置
这个位置是配置webpack额外配置的,因为vue-cli3已经帮你配置好了,但是对于这需求各种变的年代。不改是不可能的,还不如在webpack里配置呢。。吐槽一下。接下来就把下边这些代码放进去
const svgRule = config.module.rule('svg');
// 清除已有的所有 loader。
// 如果你不这样做,接下来的 loader 会附加在该规则现有的 loader 之后。
svgRule.uses.clear();
svgRule
.test(/\.svg$/)
.include.add(path.resolve(__dirname, './src/icons/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
});
const fileRule = config.module.rule('file');
fileRule.uses.clear();
fileRule
.test(/\.svg$/)
.exclude.add(path.resolve(__dirname, './src/icons/svg'))
.end()
.use('file-loader')
.loader('file-loader');
你不要纳闷,为啥配置这svg的规则又配置了下file,这个就是坑。
来先看一下package.json
这个开发依赖也没有file-loader啊,配置他干嘛。。我就为了这个都哭,看着没有,实际上有,就是这些vue/cli的某个的以来还是用的是file-loader所以你要是不配置的话,就会有两个东西去处理你的svg,文件。他会告诉你需要你一个loader,实际上你有俩。
此时按我这个配置就可以了。为了证明有,你看看这个。。
然后自己写个组件。,再用webpack的
require.context方法把那些svg导入进来。这个方法作用就是把所有的svg亿import形式引入进来。
看代码
先看组件
<template>
<svg :class="svgClass" xmlns="http://www.w3.org/2000/svg">
<use :xlink:href="iconName" xmlns:xlink="http://www.w3.org/1999/xlink" />
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
iconName() {
return `#icon-${this.iconClass}`;
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className;
} else {
return 'svg-icon';
}
}
}
};
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
用的时候就是icon-class里的就是svg你开始的命名,别整中文啊。后边这个class-name就是你自定义的class,要设置大小记得font-size可别width,height啥的。。那就很尴尬了
<svg-icon icon-class="copy" class-name="size"></svg-icon>
接下来就是如何引入的svg的进入页面的
import Vue from 'vue';
import SvgIcon from '@/components/SvgIcon'; // svg组件
// register globally
Vue.component('svg-icon', SvgIcon);
const req = require.context('./svg', false, /\.svg$/);
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);
先把组件全局注册,然后引入组件;
如果看不懂就直接百度require.context然后你就懂了。
这个时候再去main.js里引入就好了。(别忘了这一步)
import './icons'; // icon
你就可以用了,而且是页面各个角度的用。你要看一下dom结构有没有这个。
有你就大胆用吧,啥毛病没有,没有的话,是不是你svg名字给写错了。其他都没错了还是不显示就去检查这个webpack的配置吧和控制台的错误输出。其他就只有碰到了才清楚。
现在最新版给的方法是这个(先别急着用)
1.在对应vue项目里添加插件
vue add svg-sprite
2.再执行:
npm install svgo svgo-loader --save-dev
这里开发以来会增加一个vue-cli-svg-sprite和svgo和svgo-loader
因为svgo可以整理svg的某些东西,去掉或者增加,反正是可以批量处理他们,以方便我们使用。他会给我们自动生成一个已经写好的组件 到时候你引入这个组件就可以了。我的情况就是没找到原因就是一直不显示还不报错。so,我抛弃了他,使用了上边的方法,实际上vue-cli-svg-sprite的依赖也是svg-sprite-loader,没准问题也是file-loader的事,应该是我的某些配置问题。如果有大神知道原因,希望你告诉我一下吧。最近没空去探寻真理,实现了先用。
更多推荐
所有评论(0)