通用svg圖示元件——SvgIcon
阿新 • • 發佈:2022-04-17
實現一個通用的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 [email protected]
在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() } }