在维护公司内部UI库时,某些场景需要进行图标选择,去UI库中寻找显然不符合用户需求,这时候就需要封装一个图标选择器组件。
先定义一个触发框,可以用el-input,我这里使用的是基于el-input封装的输入框组件。然后使用el-popover组件进行嵌套
<template>
<div>
<el-popover
ref="popover"
placement="bottom"
popper-class="iconPicker vxe-table--ignore-clear"
:width="popperWidth"
:visible-arrow="false"
transition="el-zoom-in-top"
trigger="click">
<el-scrollbar style="height: 300px">
<div class="mainBox">
<ul class="icon-list" >
<li v-for="icon in iconList" :key="icon" class="icon" >
<i :class="[icon,{'checked': icon === checked}]" @click="handleClick(icon)"></i>
</li>
</ul>
</div>
</el-scrollbar>
<div slot="reference" class="triggerBox">
<el-input :size="size" readonly class="trigger" v-model="checked"></el-input>
</div>
</el-popover>
</div>
</template>
图标库我们是在阿里图标库进行的上传和维护,下载字体图标文件时,将iconfont.json文件也复制进项目中,在图标选择器内进行引入。
<script>
const json = require("../../packages/assets/iconfont/iconfont.json")
export default {
name: "iconPicker",
props: {
value: String,
size: String,
},
data() {
return {
popperWidth: 400,
checked: this.value
}
},
watch: {
value(val) {
this.checked = val;
}
},
computed: {
// 利用json文件组装图标
iconList() {
return this.json2FontClass(json).list;
}
},
mounted() {
// 下拉面板宽度跟随input框宽度
let trigger = this.$el.querySelector(".trigger");
this.popperWidth = trigger.offsetWidth;
},
methods: {
handleClick(icon) {
this.$refs.popover.doClose();
this.checked = icon;
this.$emit("change", icon)
this.$emit("input", icon)
},
json2FontClass(json) {
let font_family = '';
let css_prefix_text = '';
let list = [];
if (json) {
if (json.font_family) {
font_family = json.font_family;
}
if (json.css_prefix_text) {
css_prefix_text = json.css_prefix_text;
}
if (json.glyphs) {
list = json.glyphs.map((value) => font_family + " " + css_prefix_text + value.font_class);
}
}
return {
font_family: font_family,
css_prefix_text: css_prefix_text,
list: list
};
}
}
}
</script>
样式文件
<style lang="scss" scoped>
::v-deep{
.el-scrollbar__bar.is-horizontal{
display: none;
}
.el-scrollbar__wrap{
overflow-x: hidden;
}
}
.mainBox{
padding: 8px;
}
.icon-list{
list-style-type: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
gap: 8px;
li {
width: 30px;
height: 30px;
display: flex;
justify-content: center;
align-items: center;
i, svg, div {
font-size: 16px;
cursor: pointer;
}
.checked{
color: #3F8CFF;
}
}
&::after {
content: '';
flex: auto;
}
}
.triggerBox{
&:hover{
cursor: pointer;
}
.trigger{
pointer-events: none;
}
}
</style>
<style lang="scss">
.iconPicker.el-popper{
padding: 0;
border-radius: 12px;
}
</style>
至此,图标选择器封装完毕。同理还可以利用popover来封装其他下拉组件,比如下拉树形选择器等。
感谢观看。