vue-element-admin基礎(chǔ)模板中,已經(jīng)封裝好了使用svg圖標(biāo)的組件,此組件在vue-ssr項(xiàng)目中也同樣適用,所在路徑為:@/icons
,在其中我們可以找到相關(guān)的代碼,所有在文件夾中的svg圖片注冊(cè)到全局中,可以在項(xiàng)目中任意地方使用。所以圖標(biāo)均可在 @/icons/svg
。可自行添加或者刪除圖標(biāo),所以圖標(biāo)都會(huì)被自動(dòng)導(dǎo)入,無(wú)需手動(dòng)操作。
原理:
使用require.context() 函數(shù)來(lái)創(chuàng)建自己的 context
可以給這個(gè)函數(shù)傳入三個(gè)參數(shù):一個(gè)要搜索的目錄,一個(gè)標(biāo)記表示是否還搜索其子目錄, 以及一個(gè)匹配文件的正則表達(dá)式。
webpack 會(huì)在構(gòu)建中解析代碼中的 require.context()
require.context('./test', false, /\.test\.js$/);
//(創(chuàng)建出)一個(gè) context,其中文件來(lái)自 test 目錄,request 以 `.test.js` 結(jié)尾
require.context('../', true, /\.stories\.js$/);
// (創(chuàng)建出)一個(gè) context,其中所有文件都來(lái)自父文件夾及其所有子級(jí)文件夾,request 以 `.stories.js` 結(jié)尾。
使用方式:
<!-- icon-class 為 icon 的名字; class-name 為 icon 自定義 class-->
<svg-icon icon-class="password" class-name='custom-class' />
import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component
// register globally
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
將這段代碼在main中引入,或者在createApp中使用,就可以匹配到svg文件夾下的所有圖片,我們可以通過(guò)這些將svg圖片用webpack相關(guān)組件制作成svg-sprint雪碧圖
require.context("./test", false, /.test.js$/);
這行代碼就會(huì)去 test 文件夾(不包含子目錄)下面的找所有文件名以 .test.js 結(jié)尾的文件能被 require 的文件。
更直白的說(shuō)就是 我們可以通過(guò)正則匹配引入相應(yīng)的文件模塊。
require.context有三個(gè)參數(shù):
directory:說(shuō)明需要檢索的目錄
useSubdirectories:是否檢索子目錄
regExp: 匹配文件的正則表達(dá)式
之后我們?cè)鰟h改圖標(biāo)直接直接文件夾下對(duì)應(yīng)的圖標(biāo)就好了,什么都不用管,就會(huì)自動(dòng)生成 svg symbol了。
我們找到引入的svg組件@/components/SvgIcon
<template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" />
</svg>
</template>
<script>
import { isExternal } from '@/utils/validate'
export default {
name: 'SvgIcon',
props: {
iconClass: {
type: String,
required: true
},
className: {
type: String,
default: ''
}
},
computed: {
isExternal() {
return isExternal(this.iconClass)
},
iconName() {
return `#icon-${this.iconClass}`
},
svgClass() {
if (this.className) {
return 'svg-icon ' + this.className
} else {
return 'svg-icon'
}
},
styleExternalIcon() {
return {
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
}
}
}
}
</script>
svg中無(wú)法使用{{}}渲染傳遞的值,因此我們只能直接使用傳遞的iconClass,或者在computed中拼接字符串,我們可以看到iconName即為生成的svg名稱,由于拼接的字符串和iconfont中的svg格式不一樣,所以我們直接使用會(huì)沒(méi)有任何效果,我們只需要把此處的格式改為return `#:-${this.iconClass}
,
然后我們?cè)趍ain.js中引入iconfont的svg文件iconfont.js
,就可以在全局中使用iconfont中的svg標(biāo)簽了。
圖標(biāo)樣式通過(guò)svgClass來(lái)控制