vue配置svg组件
1. 创建svg目录
我们先在src下创建svg目录:src/icons/svg/
2. 到iconfont上,复制svg图标
到iconfont官网,找到自己想要的svg,点击下载-复制svg代码-粘贴到自定义的svg文件。
在src/icons/svg
目录下,创建一个文件(文件名自己随意),比如:strawberry.svg
,将刚拷贝的svg内容粘贴进去
![](https://img.haomeiwen.com/i12188741/1bded29e44c5e4d6.png)
![](https://img.haomeiwen.com/i12188741/6eba7c58483b7259.png)
3. 安装svg-sprite-loader
svg-sprite-loader
实际上是把所有的svg打包成一张雪碧图。使用每一个symbol装置对应的icon,再通过<use xlink:href="#xxx"/>
来显示你所需的icon
安装:npm install svg-sprite-loader -D
4.查看隐藏的webpack配置
在配置前,我们可能会经常忘了要怎么配置,这里向大家推荐使用一个vue-cli
提供的命令vue inspect
来查询,它可以用来查询所有的隐藏的webpack配置,这里,因为我只要查rules相关的命令
-
只查看webpack中rules的所有属性:
vue inspect --rules
[ 'vue', 'images', 'svg', 'media', 'fonts', 'pug', 'css', 'postcss', 'scss', 'sass', 'less', 'stylus', 'js', 'eslint' ]
-
查看rules中svg的配置:
vue inspect --rule svg
/* config.module.rule('svg') */ { test: /\.(svg)(\?.*)?$/, use: [ { loader: 'D:\\best-vue\\node_modules\\file-loader\\dist\\cjs.js', options: { name: 'img/[name].[hash:8].[ext]' } } ] }
5. 开始进行webpack-chain链式配置
webpack中的链式配置是通过配置chainWebpack
来配置的,它的链式调式和jquery
很像
module.exprots = {
// ...
// 链式配置webpack,config相当于webpackConfig导出的对象
chainWebpack(config) {
// 1. 修改当前项目默认的svg配置,排除我们刚设的icons目录
config.module.rule('svg')
.exclude.add(resolve('./src/icons'))
// 2. 新增一个rule, 使用svg-sprite-loader来添加icon里面的svg
config.module.rule('icons') // icons是自定义的名称
.test(/\.svg$/)
.include.add(resolve('./src/icons')).end() // end()用来退到上层链式,即回到和include平级那层
.use('svg-sprite-loader')
.loader('svg-sprite-loader') // 这里不是笔误,就是use和loader都要写
.options({
symbolId: 'icon-[name]' // 要制定下图标id,[name]就是读到的svg文件名
})
}
}
配置时,我们可以一边写一边用vue inspect --rule icons
来检验:
/* config.module.rule('icons') */
{
test: /\.svg$/,
include: [
'D:\\best-vue\\src\\icons'
],
use: [
{
loader: 'svg-sprite-loader',
options: {
symbolId: 'icon-[name]'
}
}
]
}
6. 在组件中导入并使用svg图标
我这里导入的是两个svg文件
// src/router/index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const routes = [
{
path: '/',
name: 'home',
component: () => import('@/views/Home.vue')
}
]
const router = new VueRouter({
routes
})
export default router;
<!-- App.vue -->
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<!-- src/view/Home.vue -->
<template>
<!-- 使用svg -->
<svg>
<use xlink:href="#icon-strawberry"></use>
</svg>
<svg>
<use xlink:href="#icon-strawberry2"></use>
</svg>
</template>
<script>
// 导入svg文件
import '@/icons/svg/strawberry.svg'
import '@/icons/svg/strawberry2.svg'
export default {
name: 'home'
}
</script>
![](https://img.haomeiwen.com/i12188741/201bcf582dee8560.png)
7. 设置自动批量导入
我们会发现,要使用一次,我们就得import一次,很麻烦,所以我们要想办法实现批量导入。
创建icons/index.js
文件,写入以下配置
// src/icons/index.js
// webpack创建一个以svg目录为上下文的require函数
const req = require.context('./svg', false, /\.svg$/)
// keys会获取所有的svg文件
req.keys().map(req);
// 相当于执行
// import '@/icons/svg/strawberry.svg'
// import '@/icons/svg/strawberry2.svg'
// src/main.js
// 引入批量导入svg的文件
import '@/icons'
此时,在组件内就可以不用再写import
导入语句了
<template>
<div>
<svg>
<use xlink:href="#icon-strawberry"></use>
</svg>
<svg>
<use xlink:href="#icon-strawberry2"></use>
</svg>
</div>
</template>
<script>
// import '@/icons/svg/strawberry.svg'
// import '@/icons/svg/strawberry2.svg'
export default {
name: 'home',
}
</script>
8. 封装svg组件,简化svg使用
每次调用一个svg文件时,都要重复写这段:
<svg>
<use xlink:href="#icon-strawberry"></use>
</svg>
一般看到这种,要重复调用的模板,我们都可以将其封装成一个组件,这里封装成SvgIcon.vue
,简化使用
<!-- components/SvgIcon.vue -->
<template>
<svg :class="svgClass" v-on="$listeners">
<use :xlink:href="svgName"></use>
</svg>
</template>
<script>
export default {
name: 'SvgIcon',
props: {
iconName: {
type: String,
require: true
},
className: {
type: String,
default: ''
}
},
computed: {
svgName() {
return `#icon-${this.iconName}`
},
svgClass() {
return this.className ? `svg-icon ${this.className}` : `svg-icon`
}
}
}
</script>
<style>
.svg-icon {
width: 1em;
height: 1em;
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
在src/icons/index.js
中,引入这个组件,并在vue中全局注册
// 引入组件
import SvgIcon from '@/components/SvgIcon.vue'
import Vue from 'vue'
// webpack创建一个以svg目录为上下文的require函数
const req = require.context('./svg', false, /\.svg$/)
// keys会获取所有的svg文件
req.keys().map(req);
// 相当于执行
// import '@/icons/svg/strawberry.svg'
// import '@/icons/svg/strawberry2.svg'
// 全局注册
Vue.component('svg-icon', SvgIcon)
9. 使用svg-icon组件
<template>
<div>
<!-- <svg>
<use xlink:href="#icon-strawberry"></use>
</svg>
<svg>
<use xlink:href="#icon-strawberry2"></use>
</svg> -->
<svg-icon iconName="strawberry"></svg-icon>
<svg-icon iconName="strawberry2"></svg-icon>
</div>
</template>
<script>
// import '@/icons/svg/strawberry.svg'
// import '@/icons/svg/strawberry2.svg'
export default {
name: 'home',
}
</script>
![](https://img.haomeiwen.com/i12188741/c20efbe15cfe14f8.png)