一、前言
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 组件。在开发中,不管是做大型应用还是小型应用,都离不开组件的使用和封装,应该都能收到很好的效果。