svg-sprite-loader
Настраиваем лоадер
// vue.config.js
module.exports = {
...
chainWebpack: config => {
const Sprite = config.module.rule('svg-sprite')
Sprite
.test(/\.(svg)(\?.*)?$/)
.include
// указываем путь к папке с иконками что бы не было конфликтов(например со шрифтами)
.add(path.resolve(__dirname,'src/assets/icons'))
.end()
.use('file-loader')
.loader('file-loader')
.options( {
name: 'static/img/[name].[hash:8].[ext]'
})
Sprite
.use('file-loader')
.loader('svg-sprite-loader')
}
}
Создаем компонент для иконок
<template>
<svg :class="className" xmlns="http://www.w3.org/2000/svg" :style="style" v-on="$listeners">
<use :xlink:href="`#${name}`" xmlns:xlink="http://www.w3.org/1999/xlink"/>
</svg>
</template>
<script>
export default {
name: 'svg-icon',
props: {
name: {
type: String,
required: true
},
width: {
type: Number,
},
height: {
type: Number,
}
},
mounted() {
require(`@/assets/icons/${this.name}.svg`).default.url;
},
updated() {
// у меня возникали проблемы с тем что иконки не всегда отображаются, поэтому продублировал запрос к иконке
require(`@/assets/icons/${this.name}.svg`).default.url;
},
computed: {
className() {
return 'svg-icon svg-icon--' + this.name;
},
style() {
let style = {}
if (this.width) {
style.width = this.width+'px';
}
if (this.height) {
style.height = this.height+'px';
}
return style;
}
}
};
</script>
<style>
.svg-icon {
fill: currentColor;
height: 24px;
width: 24px;
stroke: none;
}
</style>
вызов иконки
<svgicon :name="`logo`" />
Соответственно компонент svgicon либо подключаем в каждом компоненте или глобально
//main.js
//....
import SvgIcon from '@/components/SvgIcon
//....
Vue.use(SvgIcon, {
tagName: 'svgicon'
})