20、springboot3 vue3开发平台-前端-图标选择组件

1. 展示

在这里插入图片描述

2. 实现

2.1 组件实现

src\components\IconSelect\index.vue

<template>
    <div class="icon-body">
        <!-- 头部输入框 -->
      <el-input v-model="name" class="icon-search" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">
        <template #suffix>
          <el-icon class="el-input__icon"><search /></el-icon>
        </template>
      </el-input>
      <!-- 显示所有的icon和名字的容器 -->
      <div class="icon-list">
        <div class="list-container">
          <div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)">
            <div :class="['icon-item', { active: activeIcon === item }]">
                <!-- 通过组件显示图标 -->
              <svg-icon :name="item" width="16px" height="25px"></svg-icon>
              <span>{{ item }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </template>
  
  <script setup>
  import icons from './requestIcon'
  import { ref,defineProps,defineEmits } from 'vue';
  // 声明事件
  const emit = defineEmits(['selected'])
  
  defineProps({
    activeIcon: String
  })
  
  const name = ref();
  let iconList = icons;
  //console.log("selecticon icons = ", icons)
  
  function filterIcons() {
    //console.log("filterIcons == ======")
    iconList = icons
    if (name.value) {
      iconList = iconList.filter(item => item.includes(name.value))
    }
  }
  
  function selectedIcon(name) {
    emit('selected',name)
    document.body.click()
  }
  
  function reset() {
    name.value = ''
    iconList.value = icons
  }
  </script>
  
  <style rel="stylesheet/scss" lang="scss" scoped>
    .icon-body {
      width: 100%;
      padding: 10px;
      .icon-search {
        position: relative;
        margin-bottom: 5px;
      }
      .icon-list {
        height: 200px;
        overflow: auto;
        .list-container {
          display: flex;
          flex-wrap: wrap;
          .icon-item-wrapper {
            width: calc(100% / 3);
            height: 25px;
            line-height: 25px;
            cursor: pointer;
            display: flex;
            .icon-item {
              display: flex;
              max-width: 100%;
              height: 100%;
              padding: 0 5px;
              &:hover {
                background: #ececec;
                border-radius: 5px;
              }
              .icon {
                flex-shrink: 0;
              }
              span {
                display: inline-block;
                vertical-align: -0.15em;
                fill: currentColor;
                padding-left: 2px;
                overflow: hidden;
                text-overflow: ellipsis;
                white-space: nowrap;
              }
            }
            .icon-item.active {
              background: #ececec;
              border-radius: 5px;
            }
          }
        }
      }
    }
  </style>

2.2 图标加载

src\components\IconSelect\requestIcon.ts

const iconsVite = import.meta.glob('../../assets/icons/svg/*.svg')
// icon数组,最终导出
let icons = [];
// 正则表达式,匹配所有的svg文件
const re = /\.\/(.*)\.svg/
// 循环,根据正则表达式,匹配值图标
for (const icon in iconsVite) {
  // 只获取图标的名字
  let name = icon.match(re)[1].substring(icon.match(re)[1].lastIndexOf('/') + 1)
  icons.push(name)
}
//console.log("requestIcon icons = ", icons)
export default icons

注:其依赖于前部分自定义图标组件

3. 使用示例

// 导入图标选择组件
import IconSelect from '@/components/IconSelect/index.vue'


<el-form-item label="菜单图标" prop="icon">
                            <el-popover placement="bottom-start" :width="540" trigger="click">
                                <template #reference>
                                    <!-- 通过插槽实现图标选择,默认是一个有图标的输入框 -->
                                    <el-input v-model="form.icon" placeholder="请选择图标">
                                        <template #prefix>
                                            <!-- 判断是否选中了icon -->
                                            <svg-icon v-if="form.icon" slot="prefix" :name="form.icon" width="16px"
                                                height="16px" />
                                            <!-- 如果未选中,显示默认的搜索图标 -->
                                            <el-icon v-else class="el-input__icon">
                                                <search />
                                            </el-icon>
                                        </template>
                                    </el-input>
                                </template>
                                <!-- 显示选择图标的组件 -->
                                <IconSelect ref="iconSelect" @selected="handleSelect" :active-icon="form.icon" />
                            </el-popover>
                        </el-form-item>

在这里插入图片描述

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不知所云,

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值