實現一個通用的svg圖標組件
1.可以使用項目內部的svg圖標
2.也可以使用外部傳入的svg圖標
SvgIcon.vue:
<template>
<!-- 顯示外部傳入的svg -->
<div
v-if="isExternal"
:style="styleExternalIcon"
class="svg-external-icon svg-icon"
:class="className"
/>
<!-- 顯示項目內部的svg -->
<svg v-else class="svg-icon" :class="className" aria-hidden="true">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
import { isExternal } from '../utlis/validate'
export default {
name: 'SvgIcon',
props: {
// icon 圖標
icon: {
type: String,
required: true
},
// 圖標類名
className: {
type: String,
default: ''
}
},
computed: {
/**
* 判斷是否為外部圖標
*/
isExternal() {
return isExternal(this.icon)
},
/**
* 外部圖標樣式
*/
styleExternalIcon() {
return {
mask: `url(${this.icon}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.icon}) no-repeat 50% 50%`
}
},
/**
* 項目內圖標
*/
iconName() {
return `#icon-${this.icon}`
}
}
}
</script>
<style scoped>
.svg-icon {
width: 1em;
height: 1em;
/* 因icon大小被設置為和字體大小一致,而span等標簽的下邊緣會和字體的基線對齊,故需設置一個往下的偏移比例,來糾正視覺上的未對齊效果 */
vertical-align: -0.15em;
/* fill 是SVG元素的一種屬性;SVG元素的這些屬性,用於指定如何處理或者呈現元素的詳細信息
比如,fill ,對於形狀元素和文本,它定義了繪制元素的顏色。對於動畫,它定義了動畫的最終狀態。在下面的例子中,它定義了圖標的顏色。
在css中,currentColor是一個變量,這個變量的值是當前元素的color值。
如果當前元素沒有在CSS里顯示地指定一個color值,那它的顏色值就遵從CSS規則,從父元素繼承而來。 */
fill: currentColor;
overflow: hidden;
}
.svg-external-icon {
background-color: currentColor;
mask-size: cover !important;
display: inline-block;
}
</style>
validate.js:
/**
* 判斷是否為外部資源
*/
export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path)
}
批量引入svg並且注冊svg-icon組件
@/icons/index.js:
import SvgIcon from '../components/SvgIcon.vue'
// 批量引入項目內的.svg文件
const svgRequire = require.context('./svg', false, /.svg$/)
svgRequire.keys().forEach(svgIcon => svgRequire(svgIcon))
// 全局注冊 SvgIcon 組件
export default app => {
app.component('svg-icon', SvgIcon)
}
在mani.js中安裝svg-icon組件為全局組件
main.js:
import installIcons from './icons/index
installIcons(app)
安裝svg-loader讓svg得以顯示
安裝:
npm i --save-dev svg-sprite-loader@6.0.9
在vue.config.js中對svg進行修改
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
// https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
module.exports = {
chainWebpack(config) {
// 設置 svg-sprite-loader
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
.end()
}
}