当前位置: 首页 > news >正文

Element-plus弹出框popover,使用自定义的图标选择组件

自定义的图标选择组件是若依的项目的

在这里插入图片描述

1. 若依的图标选择组件

  • js文件,引入所有的svg图片
let icons = []
// 注意这里的路径,一定要是自己svg图片的路径
const modules = import.meta.glob('./../../assets/icons/svg/*.svg');
for (const path in modules) {
  const p = path.split('assets/icons/svg/')[1].split('.svg')[0];
  icons.push(p);
}

export default icons
  • vue组件
    1. 自定义的SvgIcon组件,每个人定义的方式都不用,这里重要的就是name属性:图片的名字
    2. defineProps:activeIcon: 用于返显用户已经选择或者原本就存在的图标
    3. meit:订阅selected事件,发送用户当前选择的图标
    4. defineExpose:reset方法,向外抛出方法,在父组件中可以清除搜索框中的内容
<template>
  <div class="icon-body">
    <el-input
      v-model="iconName"
      class="icon-search"
      clearable
      placeholder="请输入图标名称"
      @clear="filterIcons"
      @input="filterIcons"
    >
      <template #suffix><SvgIcon name="search"/></template>
    </el-input>
    <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 }]">
            <!--自定义的SvgIcon组件,每个人定义的方式都不用,这里重要的就是name属性:图片的名字-->
            <SvgIcon :name="item" class-name="icon" style="height: 25px;width: 16px;"/>
            <span>{{ item }}</span>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import icons from './requireIcons'
import SvgIcon from '@/components/svgicon/SvgIcon.vue'
// activeIcon: 用于返现用户已经选择的图标
const props = defineProps({
  activeIcon: {
    type: String
  }
});

const iconName = ref('');
const iconList = ref(icons);
// 订阅selected时间,发送用户当前选择的图标
const emit = defineEmits(['selected']);

// 通过js文件中的方法,将icon/svg文件夹中的图标的名字取出来
function filterIcons() {
  iconList.value = icons
  if (iconName.value) {
    iconList.value = icons.filter(item => item.indexOf(iconName.value) !== -1)
  }
}

function selectedIcon(name) {
  emit('selected', name)
  document.body.click()
}

function reset() {
  iconName.value = ''
  iconList.value = icons
}
// 向外抛出方法:在父组件中可以清除搜索框中的内容
defineExpose({
  reset
})
</script>

<style lang='scss' scoped>
   .icon-body {
    width: 100%;
    padding: 10px;
    .icon-search {
      position: relative;
      margin-bottom: 5px;
      width: 50%;
    }
    .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. 在项目中引入组件

引入组件 <IconSelect @selected="iconSelected" ref="iconSelect" :activeIcon="formData.icon"/>

  1. @selected="iconSelected":接收子组件发送的事件,图标被选中
  2. :activeIcon="formData.icon":给子组件传递图标,比如在修改数据时,数据中原本就存在图标
  3. ref="iconSelect":使用子组件的实例,调用子组件抛出的方法
<el-popover
  placement="bottom-start"
  :width="200"
  trigger="click"
>
  <!-- popover弹出框的插槽,这个插槽的决定了弹出框在页面显示的效果,这里显示的是input输入框 -->
  <template #reference>
    <el-input v-model="formData.icon" placeholder="请选择图标" clearable @clear="clearIconInput">
      <!-- input的插槽,input框前面显示的图标 -->
      <template #prefix>
        <svg-icon v-if="formData.icon" :name="formData.icon" />
        <svg-icon v-else name="search" />
      </template>
    </el-input>
  </template>
  <!-- popover弹出框的插槽,这个插槽决定弹出框弹出后显示的内容,这里显示的是IconSelect组件 -->
  <template #default>
    <!-- 弹出框的内容是自定义组件 -->
    <IconSelect style="background-color: #fff;width:500px;border:1px black solid" @selected="iconSelected" ref="iconSelect" :activeIcon="formData.icon"/>
  </template>
</el-popover>
<script setup>
const formData = reactive({
  icon: undefined,
})
// 子组件的ref,用户调用子组件中defineExpose暴露的方法
const iconSelectRef = useTemplateRef("iconSelect")
// 子组件IconSelect通过emit发送的订阅消息
const iconSelected = (name) => {
   formData.icon = name
}
// 调用子组件iconSelect的reset方法
const clearIconInput = () => {
  formData.icon = undefined
  iconSelectRef.value.reset()
}
</script>
http://www.dtcms.com/a/112335.html

相关文章:

  • sqlalchemy查询json
  • STM32CubeMX-H7-11-IIC读写MPU6050模块(上)-软件IIC协议的解析、封装,实现基本功能获取MPU6050的ID
  • 结肠镜3D视频数据集-C3VD论文中文版
  • 构建自己的私有 Git 服务器:基于 Gitea 的轻量化部署实战指南
  • 2025年3月 Scratch 图形化(二级)真题解析 中国电子学会全国青少年软件编程等级考试
  • 当 “原子” 遇上 “光腔”:量子计算的新舞台
  • 前端页面鼠标移动监控(鼠标运动、鼠标监控)鼠标防抖处理、mousemove、debounce()、事件停止触发、超时触发
  • 博途之S7通讯
  • 仿小红书社交源码+及时通讯聊天软件APP源码
  • Springboot面试篇
  • 三维扫描助力文化遗产数字化保护
  • [特殊字符] 使用 Handsontable 构建一个支持 Excel 公式计算的动态表格
  • 【调研】YOLO算法在FPGA/ZYNQ上的部署与加速
  • 文化算法初探
  • 决策树实战:用Python实现智能分类与预测
  • DE2-115分秒计数器
  • 基于javaweb的SpringBoot图片管理系统图片相册系统设计与实现(源码+文档+部署讲解)
  • 基于javaweb的SSM酒吧后台管理系统设计与实现(源码+文档+部署讲解)
  • 【棒垒球规则】全国幼儿软式棒垒球比赛规则(二)·棒球1号位
  • java流程控制04:if选择结构
  • Python 元组
  • deepseek v3-0324 Markdown 编辑器 HTML
  • uniapp的v-for不显示或者swiper-item的不显示
  • LabVIEW面向对象编程设计方法
  • Git Rebase 操作中丢失提交的恢复方法
  • 目前来讲 有哪些三维重建算法,哪个算法效果好
  • 【QT】获取文件路径中的文件名,去掉后缀,然后提取文件名中的数字
  • 判断HiveQL语句为ALTER TABLE语句的识别函数
  • Hyperlane:高性能 Rust HTTP 服务器框架评测
  • 第一期第9讲21:50