一、前言
以前引入icon图片,每次都需要指定src路径。而通过svg-sprite-loader可以在组件上写个文件名就可以引入图片了。实现icon组件涉及到的知识点如下:
1.svg-sprite-loader
首先了解一下svg-sprite-loader是什么?svg-sprite-loader是一种创建雪碧图的webpackloader,它的优点主要有两点:
- 大多数选项是自动配置的
- 精灵会自动呈现并注入页面中,您只需通过引用图像即可。
<svg><use xlink:href="#id"></use></svg>
2.vuecli环境下的webpack配置
二、vueCli配置webpack相关
- 简单的配置方式
调整 webpack 配置最简单的方式就是在 vue.config.js 中的 configureWebpack 选项提供一个对象:// vue.config.js module.exports = { configureWebpack: { plugins: [ new MyAwesomeWebpackPlugin() ] } }
- 链式操作 (高级)
webpack-chain可以定义具名的 loader 规则和具名插件,允许更细粒度地去配置。配置时使用vue inspect审查配置很方便。 通过config可以访问到module、plugin等选项,然后进入里面修改rules等配置,返回使用.end()。
chainWebpack:config=>{
config.module
.rule('svg')
.exclude.add(resolve('src/icons'));
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({symbolId:'icon-[name]'})
}
- vue inspect审查配置
该命令会将解析出来的 webpack 配置、包括链式访问规则和插件的提示打印到 stdout。- 将其输出重定向到一个文件以便进行查阅
vue inspect > output.js
- 可以通过指定一个路径来审查配置的一小部分
vue inspect module.rules.0
- 指向一个规则或插件的名字
vue inspect --rule vue vue inspect --plugin html
- 最后,你可以列出所有规则和插件的名字
vue inspect --rules vue inspect --plugins
- require.context
每次还要import svg文件,也很繁琐,为了达到更简洁的目的。可以使用webpack的require.contextAPI来动态引入icon文件夹虾的svg图片。
require.context允许您传递要搜索的目录,指示是否也应搜索子目录的标志以及用于匹配文件的正则表达式。
require.context('./test', false, /\.test\.js$/);
// a context with files from the test directory that can be required with a request endings with `.test.js`.
//在./test中找可能以.test.js结束的文件。
require.context会返回一个函数,并且该函数有keys(),id, resolve() 属性。 keys()方法返回的该模块可以处理的所有可能请求的模块的数组,简单一点就是满足该参数的模块;resolve()返回的是请求的module的id;id是该context module的id;
三、svg-sprite-loader的原理以及如何使用?
SVG Sprite最佳实践是使用symbol元素。而symbol是svg的元件,集合了三个svg图标的svg的元素会这样:
<svg>
<symbol>
<!-- 第1个图标路径形状之类代码 -->
</symbol>
<symbol>
<!-- 第2个图标路径形状之类代码 -->
</symbol>
<symbol>
<!-- 第3个图标路径形状之类代码 -->
</symbol>
</svg>
接下来要使用use才能显示,use元素非常强大,可以跨svg使用,也就是可以调用其他svg文件的元素。
<svg>
<use xlink:href="#symbolId"></use>
</svg>
因此可以分析出,svg-sprite-loader的原理就是:icon文件夹下的每个icon都对应着一个symbol,利用use指定相应的symbolId引入使用。
四、代码具体实现
- 新建icon文件夹,复制svg的代码
- vue.config.js配置
将原本的svg的rules,去除我们新建的icon目录,不使用以前的loader,然后针对当前目录的svg设置新的svg-sprite-loader。
const path = require('path')
function resolve(dir){
return path.join(__dirname,dir);
}
module.exports = {
chainWebpack:config=>{
config.module
.rule('svg')
.exclude.add(resolve('src/icons'));
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({symbolId:'icon-[name]'})
}
}
- 自动引入svg文件
在icon文件夹下新建index.js
import Vue from 'vue'
import myicon from '../components/myicon'
const req = require.context("./svg", false, /\.svg$/);
//这里还是不太明白
req.keys().map(req)
Vue.component("myicon", myicon)
- icon组件
<template>
<div>
<svg>
<use :xlink:href="iconName"></use>
</svg>
</div>
</template>
<script>
export default {
name:'myicon',
props:['name'],
computed:{
iconName(){
return '#icon-'+this.name
}
}
}
</script>
<style>
</style>