透過文字編輯器打開 SVG 圖檔 ,我們會發文件裡裡存放圖片的路徑顏色,結構很像Html,是由 TAG 和 Attribute 組成,因此同相的圖樣放大幾倍都不會影響圖片的尺寸大小。
.icon-match-event-3 { width: 24px; height: 24px; zoom: 0.8; background-position: -28px -4px; background-repeat: no-repeat; background-thumbnail: url(~@/assets/images/icon/match-event/match-event.svg); }
<svg :class="svgClass" aria-hidden="true"> <use :xlink:href="`#${svgId}`" /> </svg>
為了像 icon font 一樣使用方便,我們得透過 svg loader
npm install svg-sprite-loader --save-dev npm install svgo svgo-loader --save-dev
chainWebpack: (config) => { config.module .rule('svg') .exclude.add(resolve('src/assets/images/svg-icon')) .end() config.module .rule('icons') .test(/\.svg$/) .include.add(resolve('src/assets/images/svg-icon')) .end() .use('svg-sprite-loader') .loader('svg-sprite-loader') .options({ symbolId: 'icon-[name]', extract: true, outputPath: 'static/img/', publicPath: 'static/img/', spriteFilename: 'main.svg' }) .end() .use('svgo-loader') // 最佳化 svg (優化寫法及移除不需要的 attibute , 約可以減少30% 以上的圖檔大小) .loader('svgo-loader') .end() config.plugin('svg-sprite') // extract: true 才需要 .use(require('svg-sprite-loader/plugin')) }
<template> <svg :class="svgClass" aria-hidden="true"> <use :xlink:href="`#icon-${iconName}`" /> </svg> </template> <script> export default { name: 'SvgIcon', props: { iconName: { type: String, default: '', required: false } }, data: function() { return { } }, computed: { svgClass() { if (this.iconClass) { return 'svg-icon ' + 'icon-' + this.iconClass } else { return 'svg-icon' } } } } </script> <style> .svg-icon { display: inline-block; overflow: hidden; width: 32px; height: 32px; fill: currentColor; } </style>
<template> <div> <Layout id="app" /> <span v-if="htmlSvgString.length" v-once id="mainSvg" v-html="htmlSvgString" /> </div> </template> <script> import Layout from '@/views/layout' export default { components: { Layout }, data: function() { return { htmlSvgString: '' } }, created() { const that = this fetch('./static/images/main.svg') .then(r => r.text()) .then(text => { that.htmlSvgString = text }) } } </script> <style lang="scss"> #mainSvg { position: absolute; width: 0; height: 0; svg { position: absolute; width: 0; height: 0; } } // 如果要改色,要指定id,原本的顏色會掉,會吃父層的顏色 #icon-dropdown_b { path { fill: currentColor; } } </style>
import SvgIcon from '@/components/SvgIcon' Vue.component('Icon', SvgIcon) // 引入至 web pack const requireAll = requireContext => requireContext.keys().map(requireContext) const req = require.context('@/assets/images/svg-icon', true, /\.svg$/) requireAll(req)
// icon-name 填入 icon 的檔案名稱 <SvgIcon :icon-name="getIconFileName(tab)" class="tab-icon" />
#icon-dropdown_b { path { fill: currentColor; } }