如何封裝svg圖標組件
封裝svg圖標組件的方法有很多種,如果只是單純的想使用svg圖標,可以將svg導出fonts字體圖標使用,但這樣做會失去svg原有的樣式與尺寸,也可以當成img圖片或者背景引入,但這樣做非常繁瑣。
最近項目中需要用大量的svg圖標,這里介紹一種通過vue組件使用svg圖標的方式:
首先了解一下svg圖標的use元素。
<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元素,從而實現復用。
use元素方便的是,只要同處于一個文檔中,use都可以引用到,它可以重用單個元素,也可以重用一組<g>
或者<symbol>
元素,只需要通過id選擇器進行標時引用即可。
具體的想要了解use克隆的內容放在了哪里,以及svg更底層的內容,可參考:用CSS給SVG 的內容添加樣式
封裝vue組件
首先,將UI提供的需要使用的svg文件統一放在一個文件夾內:
├── src├── svg├── user.svg└── course.svg
復制代碼
開發vue組件:
// 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.jsconst 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
改造項目的webpack配置
由于項目是基于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圖標了。
相關文章
- 未來必熱:SVG Sprite技術介紹
- 用CSS給SVG 的內容添加樣式
如文章內容出現錯誤,敬請諒解,希望可以不吝賜教。
轉載請注明出處