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