Author: 微笑向暖_Tinicss
原文連接:juejin.im/post/5cf79b…html
封裝svg圖標組件的方法有不少種,若是隻是單純的想使用svg圖標,能夠將svg導出fonts字體圖標使用,但這樣作會失去svg原有的樣式與尺寸,也能夠當成img圖片或者背景引入,但這樣作很是繁瑣。vue
最近項目中須要用大量的svg圖標,這裏介紹一種經過vue組件使用svg圖標的方式:webpack
首先了解一下svg圖標的use元素。git
<svg>
<defs>
<g id="shape">
<rect x="0" y="0" width="50" height="50" />
<circle cx="0" cy="0" r="50" />
</g>
</defs>
<use xlink:href="#shape" x="50" y="50" />
<use xlink:href="#shape" x="200" y="50" />
</svg>
複製代碼
好比我繪製了一個id爲shape的svg元素,當我想複用時,不可能再複製粘貼一遍代碼,這時藉助use元素,讓xlink:href
指定爲#shape
,它會去尋找並克隆對應的svg元素,從而實現複用。github
use元素方便的是,只要同處於一個文檔中,use均可以引用到,它能夠重用單個元素,也能夠重用一組<g>
或者<symbol>
元素,只須要經過id選擇器進行標時引用便可。web
具體的想要了解use克隆的內容放在了哪裏,以及svg更底層的內容,可參考:用CSS給SVG 的內容添加樣式vue-cli
首先,將UI提供的須要使用的svg文件統一放在一個文件夾內:bash
├── src
├── svg
├── user.svg
└── course.svg
複製代碼
開發vue組件:svg
// svg-icon.vue
<template>
<svg :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName"></use>
</svg>
</template>
<script>
import './icons';
export default {
name: 'SvgIcon',
props: {
// svg圖標名稱
name: {
default: ''
},
// 自定義樣式
className: {
type: String,
default: ''
}
},
computed: {
iconName() {
return `#icon-${this.name}`;
},
svgClass() {
return [
'svg-icon',
this.className ? this.className:''
]
}
}
};
</script>
<style scoped>
.svg-icon {
vertical-align: -0.15em;
fill: currentColor;
overflow: hidden;
}
</style>
複製代碼
咱們指望使用svg-icon組件來統一使用全部的svg文件,經過指定name來變動對應的svg文件。
想要使用svg文件的話,還須要將全部svg文件統一加載到內存當中,可使用import 'svg/user.svg'
這種方式一個一個引用,這裏藉助require.context
一次性引入全部svg
文件。
// icons.js
const req = require.context('@svg', false, /\.svg$/);
const requireAll = requireContext => requireContext.keys().map(requireContext);
requireAll(req);
複製代碼
這個時候,還不能經過svg-icon組件指定name的方式來引用兌用svg文件。咱們還須要將每一個svg文件進一步處理,將他們文件內容的icon封裝進symbol
元素中,達到下面的使用效果:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<symbol class="icon" viewBox="0 0 970 740" id="icon-user">...</symbol>
</svg>
複製代碼
這裏能夠藉助webpack插件:svg-sprite-loader
因爲項目是基於vue-cli3定製的,因此這裏只介紹一下如何在vue-cli3中配置svg-sprite-loader
。
代碼以下:
module.exports = {
...
chainWebpack: config => {
...
config.module
.rule('svg')
.exclude.add(resolve('src/svg'))
.end();
config.module
.rule('svgs-loader')
.test(/\.svg$/)
.include.add(resolve('src/svg'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end();
}
}
複製代碼
這裏要注意一下,配置svg-sprite-loader
以前,要先替換vue-cli3自己的file-loader
規則,該loader
會把svg同圖片資源同樣單獨輸出出來,這裏配置file-loader
忽略svg下面全部的svg文件便可。
最後,在vue中就能夠經過svg-icon組件來使用對應的svg圖標了。
如文章內容出現錯誤,敬請諒解,但願能夠不吝賜教。
轉載請註明出處