前言 近日项目上想要做一个图标选择器,详细的需求如下: 可以选择 Element 的图标以及所扩展的 IconFont 图标; 值为选中图标的 CSS 类名; 展现形式:下拉列表; 选中图标后,展示该
前言
近日项目上想要做一个图标选择器,详细的需求如下:
- 可以选择 Element 的图标以及所扩展的 IconFont 图标;
- 值为选中图标的 CSS 类名;
- 展现形式:下拉列表;
- 选中图标后,展示该图标;
- 可禁用,可清除;
- 支持 change 事件。
项目使用 Element ,我们首先应该从 Element 组件库中选择合适的组件,作为图标选择器的基础(站在巨人的肩膀上,尽可能多的利用已有的开源组件功能,不要重复造轮子)。
Select 是一个很好的选择,展现形式为下拉列表,禁用和清除的功能可以直接拿来使用, prefix
插槽可以用来实现选中后图标展示功能。
组件最终的效果如下:
具体实现流程
1 架子先搭起来
从组件使用者角度来考虑,图标选择器需要对外提供以下功能点:
- v-model 绑定 value
- disabled 选项
- change 事件
使用 Select 组件作为基础,将图标选择器的架子搭起来:
<template>
<el-select :value="value" :disabled="disabled">
<el-option :value="value">
</el-option>
</el-select>
</template>
<script>
export default {
name: "icon-picker",
props: {
value: {
type: String,
required: true
},
disabled: {
type: Boolean,
default: false
}
},
model: {
prop: 'value',
event: 'change'
},
data() {
return {
};
},
methods: {
}
}
</script>
<style scoped>
</style>
2 抽取图标数据
下一步,我们将 Element 图标及 IconFont 图标的样式类数据,抽取到一个独立的文件 icons.json 中:
{
"elementIcons": [
"platform-eleme",
"eleme",
"delete-solid",
"delete",
"s-tools",
// ....
],
"iconFonts": [
"number0",
"number1",
"number2",
"number3",
"number4",
// ....
]
}
将上述图标数据引入到图标选择器组件中:
import icons from "./icons.json";
data() {
return {
icons: icons
};
}
3 生成图标下拉选项
在 <el-option>
中分别遍历 Element 及 IconFont 的图标数据,生成可点击的图标列表,当然,需要有一些样式的支持(不仅仅是图标列表的样式,还需要对 Element Select 下拉选项的一些默认的样式进行覆盖):
<el-option class="icon-picker-option" :value="value">
<div>
<ul>
<li v-for="icon in icons.elementIcons" :key="icon" @click="iconClick('el-icon-' + icon)">
<span><i :class="'el-icon-' + icon"></i></span>
</li>
<div class="clearfix"></div>
</ul>
<hr>
<ul>
<li v-for="icon in icons.iconFonts" :key="icon" @click="iconClick('iconfont icon-' + icon)">
<span><i :class="'iconfont icon-' + icon"></i></span>
</li>
<div class="clearfix"></div>
</ul>
</div>
</el-option>
<style scoped>
.clearfix {
clear: both;
}
.icon-picker-option.el-select-dropdown__item {
width: 307px;
height: auto;
max-height: 200px;
overflow-y: auto;
padding: 0;
}
.icon-picker-option.el-select-dropdown__item.hover, .icon-picker-option.el-select-dropdown__item:hover {
background-color: #fff;
cursor: default;
}
.icon-picker-option.el-select-dropdown__item.selected {
color: #606266;
font-weight: normal;
}
.icon-picker-option::-webkit-scrollbar {
width: 7px;
background-color: #eee;
}
.icon-picker-option::-webkit-scrollbar-track {
background-color: #eee;
}
.icon-picker-option::-webkit-scrollbar-thumb {
background: #d7d7d7;
border-radius: 7px;
}
.icon-picker-option > div {
cursor: default;
}
.icon-picker-option ul {
display: block;
margin: 0;
padding: 0;
}
.icon-picker-option ul > li {
display: block;
margin: 0;
padding: 0;
float: left;
text-align: center;
cursor: pointer;
width: 30px;
height: 30px;
line-height: 30px;
}
.icon-picker-option ul > li:hover {
color: #327edb;
font-size: 16px;
}
</style>
4 实现选中及清除
为 Select 添加 clearable
可清除功能,并在 clear
清除事件及图标点击事件中,通过 $emit
触发图标选择器的 change
事件,更新图标选择器选中的值:
<el-select :value="value" :disabled="disabled" clearable @clear="clearHandle">
</el-select>
methods: {
iconClick(className) {
this.$emit('change', className);
},
clearHandle() {
this.$emit('change', '');
}
}
5 展示选中图标
最后,通过 Select 组件的 prefix
插槽,我们可以对选中的图标进行展示:
<el-select :value="value" :disabled="disabled" clearable @clear="clearHandle">
<template slot="prefix">
<span class="icon-picker-selected" v-if="value !== '' && value != null">
<i :class=value></i>
</span>
</template>
</el-select>
<style scoped>
.icon-picker-selected > i {
color: #333333;
line-height: 40px;
margin-left: 6px;
font-size: 14px;
}
</style>