封装组件库-图标选择器
2023, Feb 20
实现图标选择器
基于Element-plus框架的Icon图标,封装为图标选择器。
初始配置
- 注册路由组件chooseIcon,配置为Container组件的子路由组件
- 采用路由懒加载,箭头函数异步引入组件。
- 注册通用组件ChooseIcon,为路由组件的子组件,以便组件间通信。
ChooseIcon组件
ChooseIcon组件采用Element-plus的Button组件和Dialog对话框组件,引入Icon图标,实现选择器功能。 Dialog对话框存在v-model属性,值为boolean类型,初始为false,控制对话框的显示与隐藏。
<el-dialog :title="title" v-model="dialogVisible">
父组件给子组件传递tilte和visible
<choose-icon title="选择图标" v-model:visible="visible">选择图标</choose-icon>
let visible = ref<boolean>(false)
子组件props接收,并拷贝,传递给模版
<el-dialog :title="title" v-model="dialogVisible">
let props = defineProps<{
//弹出框的标题
title: string,
//显示与隐藏
visible: boolean,
}>()
//拷贝props的visible
let dialogVisible = ref<boolean>(props.visible)
问题
初始化的visible值为false,点击按钮后,给父组件传递true。同时给props.visible开启watch监听,dialogVisible.value = true。
<el-button @click="handleClick" type="primary">
let emits = defineEmits(['update:visible'])
// 关闭遮罩层后,visible值为false,没有点击按钮,捕获不到事件
let handleClick = ()=>{
emits('update:visible', !props.visible)
}
//只能监听一次变化
watch(()=> props.visible,val => {
dialogVisible.value = val
})
此时观察父组件visible的变化发现,关闭对话框后,visible的值依然为true,而子组件的内部,由于关闭了对话框,dialogVisible的值变为了false。 因此,可以将dialogVisible的值传递给父组件,用来更新visible的值。则开启二次监听,对dialogVisible进行监听。
//对组件内部的dialogVisible进行监听
watch(()=> dialogVisible.value, val => {
emits('update:visible', val)
// console.log(val);
})
图标引入
引入所有图标,在对话框内呈现
import * as Icons from '@element-plus/icons'
<div class='item'
v-for="(item,index) in Object.keys(Icons)"
:key='index'
@click="clickItem(item)">
<div>
<component :is="`qt-icon-${toLine(item)}`"></component>
</div>
<div></div>
</div>
v-for遍历图标对象的键名,同时采用动态组件
export const toLine = (value: string)=>{
return value.replace(/(A-Z)g/, '-$1').toLocaleLowerCase()
}
图标复制功能
此时,需要实现点击icon图标,useCopy复制其名称。并且,复制完成后,关闭对话框。
let clickItem = (item: string)=>{
let text = `<qt-icon-${toLine(item)}/>`
useCopy(text)
dialogVisible.value = false
}
定义一个hooks,实现useCopy方法。思想:在文档定义一个input框,值为传参,放入文档。选中对话框,execCommand(‘Copy’)复制,最后删除对话框。
import { ElMessage } from "element-plus"
//复制文本,利用文本框
export const useCopy = (text: string)=>{
let input = document.createElement('input')
input.value = text
document.body.appendChild(input)
//选中输入框
input.select()
//执行复制操作
document.execCommand('Copy')
document.body.removeChild(input)
ElMessage.success('复制成功')
}
图标样式
Element-plus阻止了样式的修改,因此需要自定义一个类名空间,在App.vue内注册,并在修改样式的元素的父元素添加类名
.choose-icon-dialog-body-height{
.el-dialog__body{
height: 500px;
overflow: scroll;
}
}