Vue3+Element?Plus使用svg加載iconfont的處理方法
安裝依賴
由于我們是Vue3項(xiàng)目,可以使用vite
來快速創(chuàng)建一個(gè)Vu3項(xiàng)目:
npm install -g yarn yarn create vite my-vue-app --template vue // 這里我們使用vue模板,默認(rèn)是Javascript語法,如果需要ts語法則需要指定模板為vue-ts cd my-vue-app yarn yarn dev
創(chuàng)建好項(xiàng)目后,我們再來引入Element Plus
,安裝并引入的過程如下:
安裝
:
yarn add element-plus
完整引入
:
// main.js ... import ElementPlus from 'element-plus' import 'element-plus/dist/index.css' app.use(ElementPlus)
引入后,我們就可以在Vue3項(xiàng)目中使用了:
<template><el-button>按鈕</el-button> </template>
Element Plus使用Icon會比Element UI稍微麻煩點(diǎn)。首先我們需要安裝Icon的依賴:
yarn add @element-plus/icons-vue
我們在main.js
中注冊所有的圖標(biāo),當(dāng)然也可以按需引入圖標(biāo):
// main.js // 全局引入 import * as ElementPlusIconsVue from '@element-plus/icons-vue' ... for (const [key, component] of Object.entries(ElementPlusIconsVue)) {app.component(key, component) }
el-icon
的使用:
<template><el-icon><Edit /></el-icon> </template> <script setup> // import {Edit} from '@element-plus/icons-vue' // 按需引入,如果已經(jīng)全局引入了就不需要按需引入 </script>
Element Plus的el-icon
使用的是svg
,這與Element UI使用的類名有很大的不同,也就是說我們無法直接在el-icon
中使用iconfont
的圖標(biāo)。雖然Element Plus的圖標(biāo)已經(jīng)能滿足大部分場景的需求,但是一些特殊場景只能從iconfont
或者自定義的圖標(biāo)上獲取。
那么有沒有辦法將iconfont
封裝成svg,并給el-icon
調(diào)用呢?
將iconfont封裝成svg
可縮放矢量圖形(Scalable Vector Graphics),簡稱SVG,是一種基于XML的,可用于描述二維的矢量圖形。SVG可以優(yōu)雅而簡潔的渲染不同大小的圖形,并且可以被無限縮放并且保持不失真或者降低質(zhì)量,這一特性比JPEG
、PNG
等好用太多。SVG的內(nèi)容相當(dāng)多,感興趣的可以去MDN上查看文檔:SVG。我們這里只是簡單實(shí)用SVG來封裝iconfont。
首先我們新建一個(gè)SvgIcon.vue
的文件,
<template><svg :class="classList" aria-hidden="true"> <use :xlink:href="iconName" rel="external nofollow" :fill="color" /></svg> </template> <script setup> import { computed } from 'vue'; const props = defineProps({className: { type: String, default: ''},iconClass: { type: String, required: true},color: { type: String, default: '#409eff'},size: { type: String, default: '20px'} }) const classList = computed(() => {return ['icon', props.className || ''] }) const iconName = computed(() => {return `#${props.iconClass}` }) </script> <style scoped> .icon {/* v-bind是Vue3才支持的功能,可以將CSS的值與js的值綁定 */width: v-bind('props.size');height: v-bind('props.size');position: relative;vertical-align: -2px;fill: currentColor; } </style>
這樣就將iconfont
封裝成了svg來調(diào)用了,這里我們重點(diǎn)說幾個(gè)屬性:
- aria-hidden:默認(rèn)為false,設(shè)置為true表示會把整個(gè)元素包括子元素從可訪問樹(AOM)上移除,但是在DOM樹上還是存在的
- xlink:href:use元素的屬性
- v-bind:Vue3的特性,可用于關(guān)聯(lián)CSS和js
- fill:如果在動(dòng)畫接收還需要保持動(dòng)畫的值,可用于設(shè)置顏色
如何使用
使用已經(jīng)封裝好的SvgIcon.vue
比較簡單,就和正常的組件一樣使用即可。例如:
<template><SvgIcon :icon-class="icon-pointer"></SvgIcon> </template> <script setup> import SvgIcon from './SvgIcon.vue' </sript>
如果不想在局部注冊組件,也可以注冊為全局組件:
// main.js import SvgIcon from '@/SvgIcon.vue' ... app.component('SvgIcon', SvgIcon);
作為SVG組件,我們也可以直接使用在el-icon
中,這樣就可以添加任意iconfont
到el-icon
中了:
<template><el-icon><SvgIcon :icon-class="icon-pointer"></SvgIcon></el-icon> </template>
按理說到這里,本篇教程就應(yīng)該結(jié)束了。但是,在使用的過程中,按照正常的方式設(shè)置的hover
樣式不生效,筆者嘗試了幾種方案,最終放棄hover
,采用監(jiān)聽鼠標(biāo)事件的方式解決。
設(shè)置”hover“樣式
SVG不同于class
樣式,其無法直接通過修改hover
樣式來設(shè)置鼠標(biāo)懸浮在圖標(biāo)上面時(shí)顏色改變,這個(gè)時(shí)候我們就需要換一種思路了。我們在SvgIcon.vue
中傳入了color
,并且通過fill
將color
作用到SVG上,因此我們可以在父組件中修改color
的值來實(shí)現(xiàn)"hover"效果。
<template><div @mouseenter="() => handleMouseenter" @mouseleave="() => handleMouseleave"><SvgIcon :icon-class="icon-pointer" :color="color"></SvgIcon></div> </template> <script setup> import {ref} from 'vue' const color = ref('red') const handleMouseenter = () => {color.value = 'blue' } const handleMouseleave = () => {color.value = 'red' } </sript>
上面的例子中適用于單個(gè)SvgIcon
,如果是多個(gè)的話,就需要進(jìn)一步改造了:
<template><div v-for="(item, index) in list" @mouseenter="($event) => handleMouseenter($event, index)" @mouseleave="($event) => handleMouseleave($event, index)"><SvgIcon :icon-class="icon-pointer" :color="hoverIconIndex == index ? 'blue' : 'red'"></SvgIcon></div> </template> <script setup> import {ref} from 'vue' const list = ref([{name: '張三'} ]) const color = ref('red') const hoverIconIndex = ref(-1) const handleMouseenter = (event, index) => {hoverIconIndex.value = index; } const handleMouseleave = (event, index) => {hoverIconIndex.value = -1; } </sript>
對比來看,其實(shí)也不復(fù)雜。
為什么圖標(biāo)顏色無法修改?
可能有點(diǎn)朋友按照上述的步驟操作后,發(fā)現(xiàn)并不能修改圖標(biāo)顏色,如果不是代碼有誤,那應(yīng)該就是導(dǎo)入的iconfont有問題。一般我們會直接在iconfont官網(wǎng)下載圖標(biāo):
將下載好的壓縮包解壓后,只復(fù)制iconfont.js
到項(xiàng)目中即可:
// main.js ... import '@/assets/iconfont/iconfont.js';
我們來看一下iconfont.js
中icon-close1
和icon-close
的源碼:
可以發(fā)現(xiàn),這兩個(gè)圖標(biāo)最大的差別就是一個(gè)有fill
,另一個(gè)沒有,而這就是問題的關(guān)鍵。如果某一個(gè)圖標(biāo)的fill不為空,那么作為svg引用時(shí)將無法修改填充色。
舉個(gè)例子:
<template><div> <SvgIcon :color="'red'" :icon-class="'icon-close'"></SvgIcon> <SvgIcon :color="'red'" :icon-class="'icon-close1'"></SvgIcon> </div> </template>
運(yùn)行結(jié)果:
遇到這個(gè)問題應(yīng)該怎么解決呢,一種方式就是手動(dòng)刪除所有Icon的fill
屬性,另一個(gè)就是在iconfont上面使用批量去色。
批量去色后,我們再次下載圖標(biāo),并解壓后替換掉原來的iconfont.js
,再去源碼看看就會發(fā)現(xiàn)所有圖標(biāo)的fill
都沒有了,而且也可以修改顏色。
總結(jié)
本文詳細(xì)介紹了如何在Element Plus中使用iconfont,簡單的說就是要將其封裝成SVG,并且支持動(dòng)態(tài)修改顏色。雖然操作上不難,但是容易踩一些坑,你學(xué)會了嗎?
相關(guān)文章
vue-cli對element-ui組件進(jìn)行二次封裝的實(shí)戰(zhàn)記錄
組件類似于需要多個(gè)地方用到的方法,在Vue中組件就是一種復(fù)用(經(jīng)常使用)一個(gè)功能的手段,下面這篇文章主要給大家介紹了關(guān)于Vue?element?ui二次封裝的相關(guān)資料,需要的朋友可以參考下2022-06-06vue如何點(diǎn)擊多個(gè)tab標(biāo)簽打開關(guān)閉多個(gè)頁面
這篇文章主要介紹了vue如何點(diǎn)擊多個(gè)tab標(biāo)簽打開關(guān)閉多個(gè)頁面,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09vue數(shù)組對象排序的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue數(shù)組對象排序的實(shí)現(xiàn)代碼,這里整理了詳細(xì)的代碼,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2018-06-06webpack轉(zhuǎn)vite的詳細(xì)操作流程與問題總結(jié)
Vite是新一代的前端開發(fā)與構(gòu)建工具,相比于傳統(tǒng)的webpack,Vite 有著極速的本地項(xiàng)目啟動(dòng)速度(通常不超過5s)以及極速的熱更新速度(幾乎無感知),下面這篇文章主要給大家介紹了關(guān)于webpack轉(zhuǎn)vite的詳細(xì)操作流程與問題總結(jié)的相關(guān)資料,需要的朋友可以參考下2023-03-03Vue3中同時(shí)定義多個(gè)插槽的實(shí)現(xiàn)示例
本文主要介紹了Vue3中同時(shí)定義多個(gè)插槽的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12如何解決element-ui動(dòng)態(tài)加載級聯(lián)選擇器默認(rèn)選中問題
這篇文章主要介紹了如何解決element-ui動(dòng)態(tài)加載級聯(lián)選擇器默認(rèn)選中問題,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-09-09深入解析Vue源碼實(shí)例掛載與編譯流程實(shí)現(xiàn)思路詳解
這篇文章主要介紹了Vue源碼實(shí)例掛載與編譯流程實(shí)現(xiàn)思路詳解,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-05-05