基于element-plus重新封装icon自定义样式组件

Xxd Lv2

重新封装icon自定义hover样式组件

封装方法

icon图标在element-plus中只提供了color和size的属性,因此当需要直接将icon作为按钮使用时,无法按需进行hover颜色的设置。简单举个例子:如果我在一个按钮框内有多个不同icon作为按钮,此时element-plus给我提供了大小和颜色属性的设置,但是我无法简便地设置鼠标悬浮颜色。能够生效的解决方案是给这里的每个icon加一个class类名然后设置相应的:hover颜色属性。但是可能存在的问题是假如我还有许多地方需要使用带hover样式的icon作为按钮,那么就需要多写许多重复相似的css代码,因此萌生出了将icon重新进行封装的想法。

以下直接放出封装的组件代码,之后进行详细解释

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
<template>
<el-icon
:style="hoverClass"
@mouseenter="changeHover()"
@mouseleave="noHover()"
>
<component class="icon" :is="IconMap[iconName]"></component>
</el-icon>
</template>

<script setup>
import {computed, defineProps, onMounted,ref, defineAsyncComponent} from "vue"
import {CloseBold,ZoomIn,InfoFilled,Download,CircleClose,ZoomOut,Setting } from '@element-plus/icons-vue'

// 将图标进行组件化实现自定义,因为标签的css hover属性将不可用,所以需要手写mouseenter和mouseleave事件
// 这里props加上双引号进行严格大小写限制,如果不加双引号,那么props是按照vue3驼峰命名规范,自动进行大小写转换和横杠添加
const props = defineProps({
"iconName":{
required: true
},
"iconColor":{
type: String,
default: '#000'
},
"hoverColor":{
type: String,
default: '#8b8b8b'
},
"size":{
type: String,
default: '30'
}
})

// 判断是否为鼠标悬浮状态
const isHover = ref(false)
const changeHover = ()=>{
isHover.value=true
}
const noHover = ()=>{
isHover.value=false
}

// 对图标进行样式添加,分别对应的是hover时的颜色变化;鼠标悬浮样式;图标宽高
const hoverClass = computed(()=>({
color: isHover.value?props.hoverColor:props.iconColor,
cursor: 'pointer',
width: `${props.size}px`,
height: `${props.size}px`
}))

// 这里对图标名字进行映射映射,因为props传来的数据仅仅是string字符串,而通过:is双向绑定的是组件,因此需要作相应的映射
const IconMap = {
"CloseBold": CloseBold,
"InfoFilled": InfoFilled,
"Download": Download,
"CircleClose": CircleClose,
"ZoomIn": ZoomIn,
"ZoomOut": ZoomOut,
"Setting": Setting
};

</script>

<style lang="scss" scoped>
.el-icon{
cursor: pointer;
.icon{
width: 100%;
height: 100%;
}
}
</style>
  • 首先需要知道icon图标的引入方式,element-ui和element-plus的引入方式是有区别的。在element-ui中引入方式是通过class类名引入<i class="el-icon-info"></i>,而element-plus是组件引入的方式<el-icon><Download/></el-icon>。提一下这个的原因是它会关系到封装的组件怎么使用对应的图标。

  • 由于封装组件后css是不能跨组件生效hover的,因此需要自己写hover的事件。首先声明一个isHover的响应式数据,然后使用mouseenter(鼠标进入)和mouseleave(鼠标离开)添加鼠标悬浮事件,当mouseenter时将isHover的值置为true,当mouseleave时将isHover的值置为false。需要注意isHover是通过ref声明的,那么要在setup中操作ref响应式数据就必须加上value,否则会报错。(举例:isHover.value)

  • 使用props获取父传子的参数,四个参数分别为icon-name(图标名称)、icon-color(图标颜色)、hover-color(悬浮颜色)、size(图标大小),其中icon-name为必须指定的参数,icon-color、hover-color、size是非必要参数,它们有各自默认的值

  • el-icon双向绑定:style指定样式,使用computed计算属性监听hoverClass的变化,这里主要是监听hover时的颜色变化。hoverClass四个属性分别为color、cursor、width、height。color使用三元表达式来控制不同的图标颜色,isHover值为真时,显示hoverColor;isHover值为假时,显示iconColor

  • 最后是图标的引入,这里使用<component :is="组件名"></component>的方式引入图标,这里有几点需要注意
    – 1. :is绑定的参数必须是组件而不能是单纯的字符串名字,否则是无法成功拿到组件的
    – 2. props传过来的iconName参数是一个字符串,并且vue本身是推崇camel-case驼峰命名法。当进行组件间传值时,vue3会自动将驼峰式命名的属性值进行大小写和横杠的转换(比如传入的值是CirclePlus,vue会将其变为circle-plus。传入值为Download则转换为download)。引入组件名字是严格遵守大小写的,因此解决这个问题的方案就是给props加上双引号即可严格大小写,此时接收的值该是什么就是什么
    – 3. 解决第1点:is指定组件的问题,拿到props值以后需要作映射,建立iconMap用来进行字符串和icon组件的映射,之后即可用于component标签来指定相关的图标

自定义组件中的图标引用

自定义icon的话仍然是需要引入element的icon图标的(毕竟没有图标,再怎么改样式也没有用),原先想法是直接全部引入,然后查找筛选需要使用到的图标。但是感觉全部引入不太符合自己想要的效果,于是仍旧采用按需引入的方式。引入图标的方式和一般方式没有区别,但是一定要在iconMap中作好相应的映射

使用方式

在需要使用带有自定义hover样式图标的地方引入该组件

1
2
3
4
5
6
7
8
9
10
11
12
13
<template>
<div>
<my-icon icon-name="ZoomIn" icon-color="#64B2C0" hover-color="#0C6E80" size="40"></my-icon>
<my-icon icon-name="ZoomOut" icon-color="#3DAF87" hover-color="#016E48"></my-icon>
<my-icon icon-name="Download" icon-color="#FFA359" hover-color="#F16831"></my-icon>
<my-icon icon-name="CircleClose" icon-color="#FF7C59" hover-color="#D0360E"></my-icon>
</div>
</template>
<script setup>
import myIcon from '@/components/myicon/myicon.vue'
</script>
<style lang="scss" scoped>
</style>

输入的参数分别为图标名称、图标颜色、hover颜色以及图标大小

tips

代码块标题用html只是为了代码高亮显示,实际代码是vue3语法

  • 标题: 基于element-plus重新封装icon自定义样式组件
  • 作者: Xxd
  • 创建于 : 2023-04-21 22:31:32
  • 更新于 : 2024-02-07 03:57:05
  • 链接: https://blog.xxdoge.site/2023/04/21/基于element-plus重新封装icon自定义样式组件/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
 评论
此页目录
基于element-plus重新封装icon自定义样式组件