一、前言
Element Plus 是一套基于 Vue 3.0 的桌面端组件库,它可以很方便地实现各种样式的组件,就连图标选择器这样的小功能也不在话下。不过今天我们要做的是——封装 Element Plus 的图标选择器。
二、安装
安装 Element Plus:
npm i element-plus -S
三、预览
先看一下我们要实现的效果:
https://cdn.jsdelivr.net/gh/xugaoyi/image_store/blog/20210823232623.gif
四、封装
首先我们需要在 `main.js` 中引入 `Element Plus`:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'createApp(App).use(ElementPlus).mount('#app')
然后我们要封装一个图标选择器组件,这里我们命名为 `IconPicker`,并将其注册为全局组件:
import { Upload, Dialog, RadioGroup, RadioButton, Input, Button } from 'element-plus'
import { computed, defineComponent, ref, watch } from 'vue'export default defineComponent({name: 'IconPicker',components: {ElUpload: Upload,ElDialog: Dialog,ElRadioGroup: RadioGroup,ElRadioButton: RadioButton,ElInput: Input,ElButton: Button},props: {value: {type: String,required: true},prefixIcon: {type: String,default: 'el-icon-more'}},emits: ['update:value'],setup(props, { emit }) {const showIconPicker = ref(false) // 是否显示图标选择器const searchText = ref('') // 搜索文本框的值const searchResults = ref([]) // 搜索结果// 所有图标名称列表const icons = ['el-icon-info','el-icon-warning',// ...'el-icon-close']// 根据搜索文本过滤图标名称const filteredIcons = computed(() => {return icons.filter(icon => icon.includes(searchText.value))})// 根据搜索文本过滤图标分类const iconCategories = computed(() => {const categories = []for (let i = 0; i < filteredIcons.value.length; i++) {const icon = filteredIcons.value[i]const category = icon.split('-')[0]if (!categories.includes(category)) {categories.push(category)}}return categories})// 根据当前搜索结果生成分类列表const categoryList = computed(() => {const list = []for (let i = 0; i < iconCategories.value.length; i++) {const category = iconCategories.value[i]const icons = filteredIcons.value.filter(icon => icon.split('-')[0] === category)list.push({name: category,icons})}return list})// 当搜索文本发生变化时重新过滤图标watch(searchText, () => {searchResults.value = filteredIcons.value})// 打开图标选择器const openIconPicker = () => {showIconPicker.value = true}// 关闭图标选择器const closeIconPicker = () => {showIconPicker.value = false}// 选择一个图标const selectIcon = (icon) => {emit('update:value', icon)closeIconPicker()}return {showIconPicker,searchText,searchResults,categoryList,openIconPicker,closeIconPicker,selectIcon}}
})
五、使用
在需要使用图标选择器的地方,我们只需要通过 `v-model` 绑定一个变量即可:
<template><div><el-input v-model="icon" readonly /><el-button type="primary" @click="openIconPicker">选择图标</el-button><icon-picker v-model="icon" /></div>
</template><script>
import IconPicker from './components/IconPicker.vue'
import { defineComponent, ref } from 'vue'export default defineComponent({name: 'App',components: {IconPicker},setup() {const icon = ref('el-icon-info')return {icon}}
})
</script>
最后我们只需要在 `main.js` 中引入我们封装的 `IconPicker` 组件:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import App from './App.vue'
import IconPicker from './components/IconPicker.vue'const app = createApp(App)app.use(ElementPlus)
app.component('IconPicker', IconPicker)app.mount('#app')
六、总结
至此,我们已经完成了一个图标选择器的封装工作。封装这个小组件的意义不在于实现这个功能,更在于让我们了解如何封装一个 Vue 组件。在开发中,不管是做大型应用还是小型应用,都离不开组件的使用和封装,应该都能收到很好的效果。