SVG图片选择库组件封装及使用

需求

需求: 在项目中通常需要做菜单管理,想要让左侧菜单好看一点,一般都会选择添加图标,需要自定义选择喜欢的图标,得提供一个有选择项的图标库

延伸需求:在项目中通常可能有好几个图标选择库,可能每个可选择图标库里的图标都不能相同,这就需要我们做区分展示

前置条件

需要使用到svg图片,以前有写下载使用svg图片的文章,可以参考一下
链接:在vue中使用svg

图例

1. 菜单图标库

在这里插入图片描述
在这里插入图片描述

2. 场景图标库

在这里插入图片描述
在这里插入图片描述

实现

svg文件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以在svg文件夹的下级创建scene文件夹,在svg文件夹中的svg图片属于菜单图标库(不包含scene文件夹中的图片),scene文件夹中的svg图片属于场景图标库,如果想美观一点可以把菜单图标库的图标用文件夹归纳一下,重要的是icons文件夹下的index.js文件中的匹配

index.js文件

import Vue from 'vue'
import SvgIcon from '@/components/SvgIcon'// svg component

Vue.component('svg-icon', SvgIcon)

const req = require.context('./svg', false, /\.svg$/)
//温馨提示:要想使用scene文件夹中的图片一定要写这个哦
const scenereq = require.context('./svg/scene', false, /\.svg$/) 
const requireAll = requireContext => requireContext.keys().map(requireContext)
requireAll(req)
requireAll(scenereq)

1. 菜单图标组件

组件(@/components/IconSelect)
  1. index.vue文件
<template>
  <div class="icon-body">
    <el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons">
      <i slot="suffix" class="el-icon-search el-input__icon" />
    </el-input>
    <div class="icon-list">
      <div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
        <svg-icon :icon-class="item" style="height: 30px;width: 16px;" />
        <span>{{ item }}</span>
      </div>
    </div>
  </div>
</template>
<script>
import icons from './requireIcons'
export default {
  name: 'IconSelect',
  data() {
    return {
      name: '',
      iconList:icons
    }
  },
  mounted(){
    
  },
  methods: {
    filterIcons() {
      this.iconList = icons
      if (this.name) {
        this.iconList = this.iconList.filter(item => item.includes(this.name))
      }
    },
    selectedIcon(name) {
      this.$emit('selected', name)
      document.body.click()
    },
    reset() {
      this.name = ''
      this.iconList = icons
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
  .icon-body {
    width: 100%;
    padding: 10px;
    .icon-list {
      height: 200px;
      overflow-y: scroll;
      div {
        height: 30px;
        line-height: 30px;
        margin-bottom: -5px;
        cursor: pointer;
        width: 33%;
        float: left;
      }
      span {
        display: inline-block;
        vertical-align: -0.15em;
        fill: currentColor;
        overflow: hidden;
      }
    }
  }
</style>
  1. requireIcons.js
const req = require.context('../../icons/svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()

const re = /\.\/(.*)\.svg/

const icons = requireAll(req).map(i => {
  return i.match(re)[1]
})

export default icons
使用
<el-form-item label="菜单图标">
  <el-popover placement="bottom-start" width="460" trigger="click" @show="$refs['IconSelect'].reset()">
    <IconSelect ref="IconSelect" @selected="selected"/>
    <el-input slot="reference" v-model="form.icon" placeholder="点击选择图标">
      <svg-icon v-if="form.icon" slot="prefix" :icon-class="form.icon" class="el-input__icon" style="height: 32px;width: 16px;"/>
      <i v-else slot="prefix" class="el-icon-search el-input__icon" />
    </el-input>
  </el-popover>
</el-form-item>
<script>
import IconSelect from '@/components/IconSelect'
export default {
  components: { IconSelect},
  data(){
    form:{
      icon:undefined
    }
  },
  methods:{
    // 选择图标
    selected(name) {
      this.form.icon = name
    },
  }
}
</script>

2. 场景图标组件

组件(@/components/SceneIconSelect)
  1. index.vue文件
<template>
  <el-popover placement="bottom-start" width="368" trigger="click" popper-class="sence-icon-popover" @show="reset">
    <div class="icon-body">
      <div class="icon-list">
        <div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)">
          <svg-icon :icon-class="item" :class="selectIcon===item?'active-svg':'svg'" />
        </div>
      </div>
    </div>
    <div slot="reference" class="sence-icon">
      <svg-icon slot="prefix" :icon-class="selectIcon" class="el-input__icon" style="height:24px;width:24px;fill:#606266;"/>
    </div>
  </el-popover>
</template>
<script>
import icons from './requireIcons'
export default {
  name: 'SceneIcon',
  props:{
    selectIcon:String
  },
  data(){
    return{
      name: '',
      iconList:icons
    }
  },
  methods:{
    filterIcons() {
      this.iconList = icons
      if (this.name) {
        this.iconList = this.iconList.filter(item => item.includes(this.name))
      }
    },
    selectedIcon(name) {
      this.$emit('selected', name)
      document.body.click()
    },
    reset() {
      this.name = ''
      this.iconList = icons
    }
  }
}
</script>
<style rel="stylesheet/scss" lang="scss" scoped>
.icon-body {
  width: 100%;
  .icon-list {
    height: 128px;
    overflow-y: auto;
    padding: 13px;
    div {
      height: 24px;
      line-height: 24px;
      margin: 5px;
      cursor: pointer;
      width: 24px;
      float: left;
      display: flex;
      align-items: center;
      justify-content: center;
      .svg{
        width: 24px;
        height: 24px;
      }
      .active-svg{
        width: 24px;
        height: 24px;
        fill: $--color-mian !important;
      }
      &:hover,&:active,&:focus{
        .svg{
          fill: $--color-mian !important;
        }
      }
    }
  }
}
.sence-icon{
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid #DCDFE6;
}
</style>
<style lang="scss">
.sence-icon-popover{
  padding: 0 !important;
  border-radius: 0;
  border: 1px solid #DCDFE6;
  .popper__arrow{
    border-bottom-color: #DCDFE6 !important;
  }
}
</style>
  1. requireIcons.js
const req = require.context('../../icons/svg/scene', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys()

const re = /\.\/(.*)\.svg/

const icons = requireAll(req).map(i => {
  return i.match(re)[1]
})

export default icons
使用
<el-form-item label="场景图标" prop="icon">
  <SceneIconSelect ref="SceneIconSelect" v-model="form.icon" @selected="selected" :selectIcon="form.icon"></SceneIconSelect>
</el-form-item>
<el-form-item label="图标背景色" prop="color" class="picker-color">
  <el-color-picker v-model="form.color" :class="form.color?'color-picker':'none-color-picker'"></el-color-picker>
</el-form-item>
<script>
import SceneIconSelect from '@/components/SceneIconSelect'
export default {
  components: { SceneIconSelect},
  data(){
    form:{
      icon:'检修', //默认图标
      color:'#0095FF' //默认颜色
    }
  },
  methods:{
    // 选择图标
    selected(name) {
      this.form.icon = name
    },
  }
}
</script>
<style lang="scss" scped>
.picker-color{
  ::v-deep .el-form-item__content{
    height: 32px;
  }
  .color-picker{
    ::v-deep .el-color-picker__trigger{
      padding: 0;
      border: 0;
      border-radius: 0;
      .el-color-picker__color{
        border: 0;
        border-radius: 0;
      }
    }
  }
  .none-color-picker{
    ::v-deep .el-color-picker__trigger{
      padding: 0;
      border: 0;
      border-radius: 0;
      .el-color-picker__color{
        border: 1px solid #DCDFE6;
        border-radius: 0;
      }
    }
  }
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/194906.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第5代PCIe技术PCIe 5.0详解

前言 PCIe 5.0 第5代PCIe技术PCIe5.0速度是 PCIe 4.0 的两倍&#xff0c;并具有向下兼容性。PCIe 5.0 协议分析仪能够支持 32GT/秒的数据链路速度操作&#xff0c;同时具有卓越的内存、存储容量和分段功能&#xff0c;可捕获更大容量的上行和下行流量。什么是 PCIe 5.0&#x…

mysql账户密码获取

数据库安装目录 MySQL\data\mysql 里面的user.MYD文件&#xff0c;需要编译查看 数据库里的user表 库下面的user表拿到后&#xff0c;直接解密密码即可 网站配置文件 conn、config、data、sql、common 、inc这些文件 比如pikachu\inc目录下的config.inc.php文件的内容会显示…

Docker和Kubernetes:区别与优势对比

在现代软件开发和部署中&#xff0c;Docker和Kubernetes是两个备受关注的技术。本文将对Docker和Kubernetes进行比较&#xff0c;探讨它们的区别和各自的优势。 引言 在过去的几年中&#xff0c;容器技术得到了迅速的发展&#xff0c;并且在现代软件交付和部署中扮演着越来越重…

智能优化算法应用:基于正余弦算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于正余弦算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于正余弦算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.正余弦算法4.实验参数设定5.算法结果6.参考文献7.…

Vue3-pnpm包管理器创建项目

一些优势&#xff1a;比同类工具快2倍左右、节省磁盘空间 官网&#xff1a;pnpm - 速度快、节省磁盘空间的软件包管理器 | pnpm中文文档 | pnpm中文网 npm升级到yarn再升级到pnpm&#xff08;速度更快&#xff09; 安装方式&#xff1a;npm install -g pnpm 创建项目&#…

基于多图卷积-循环神经网络的地铁短时客流预测

1 文章信息 论文题目为《Multi-Graph Convolutional-Recurrent Neural Network (MGC-RNN) for Short-Term Forecasting of Transit Passenger Flow》的一篇2022年10月发表在IEEE TRANSACTIONS ON INTELLIGENT TRANSPORTATION SYSTEMS的基于多图卷积-循环神经网络的地铁短时客流…

浅谈无线测温系统在海上石油平台高压配电盘的应用-安科瑞 蒋静

摘要&#xff1a;海上石油平台的封闭式中高压配电盘在平台电力系统起着十分重要的作用&#xff0c;通过统计其配电盘的 大部分故障为前期的热效应引起&#xff0c;由于配电盘内部空间封闭狭小&#xff0c;所以无法进行人工巡查测温&#xff0c;这给油田的供电系统埋下了一定的潜…

【Java并发】聊聊不安全的HashMap以及ConcurrentHashMap

在实际的开发中&#xff0c;hashmap是比较常用的数据结构&#xff0c;如果所开发的系统并发量不高&#xff0c;那么没有问题&#xff0c;但是一旦系统的并发量增加一倍&#xff0c;那么就可能出现不可控的系统问题&#xff0c;所以在平时的开发中&#xff0c;我们除了需要考虑正…

IDEA懒人必备插件:自动生成单元测试!

IDEA懒人必备插件&#xff1a;自动生成单元测试&#xff01; 前言1、打开设置 File-->settings-->Plugins&#xff0c; 搜索 Squaretest2、安装完成后重启idea &#xff0c;你会发现&#xff0c;导航栏位置已经多了一个选项3、接着就在你想要测试的类中 用快捷键 altInse…

小程序如何进行版本回退

当商家决定回退小程序版本时&#xff0c;可能是因为新版本出现了一些问题或者不符合预期&#xff0c;需要恢复到之前的稳定版本。下面具体介绍怎么回退小程序的版本。 在小程序管理员后台->版本设置处&#xff0c;点击版本回退。确认后&#xff0c;小程序会回退到上一次的版…

瑞数五代ast反混淆笔记二

第一部分 瑞数五代ast反混淆笔记一 第二部分 瑞数五代ast反混淆笔记二 文章目录 前言一、分析思路二、轨迹合并思路三、避免重复调用一个轨迹四、自己调用自己所在的函数五、语句中包含if的处理六、语句中包含try的处理七、节点中包含影响自身值的操作总结 前言 当if转为switc…

PS修容美白插件Portraiture2024

Portraiture 4是一款强大的PS和Lightroom插件&#xff0c;能快速发现照片中的人脸和皮肤&#xff0c;支持全身皮肤部分识别&#xff0c;并升级支持自动识别照片中的面部特征。它结合AI人工深度学习&#xff0c;处理大尺寸原片可提高效率至少1倍以上。Portraiture能实现智能磨皮…

OCP Java17 SE Developers 复习题07

答案 答案 B, D. Iguana does not compile, as it declares a static field with the same name as an instance field. Records are implicitly final and cannot be marked abstract, which is why Gecko compiles and Chameleon does not, making option B correct. Noti…

利用ambari搭建Hbase高可用

初始环境&#xff1a; 节点名称服务名ambari-hadoop1ambari-hadoop2region serverambari-hadoop3hmater、 region server 计划为ambari-hadoop1添加hmaster&#xff0c;以避免hmaster的单点故障、 step1&#xff1a;添加备用Hmaster step2&#xff1a;选择ambari-hadoop1作为…

PostgreSQL 数据脱敏方式盘点

数据脱敏是一种广泛采用的保护敏感数据&#xff08;如信用卡&#xff0c;社保卡&#xff0c;地址等信息&#xff09;的方法。脱敏数据不仅仅是为了保护你和客户的数据安全&#xff0c;在一些情况下&#xff0c;法律也有相应要求&#xff0c;最著名的例子就是 GDPR。 市面上也有…

VR全景技术助力政务服务大厅数字化,打造全新政务服务体验

引言&#xff1a; 随着科技的飞速发展&#xff0c;虚拟现实&#xff08;VR&#xff09;技术逐渐走进人们的视野。VR全景技术作为VR领域的一项重要应用&#xff0c;以其沉浸式、交互式的特点&#xff0c;正逐渐渗透到各行各业。政务服务大厅作为相关部门与民众之间的桥梁&#…

Day43力扣打卡

打卡记录 子数组的最小值之和&#xff08;乘法原理 单调栈&#xff09; 大佬的题解 class Solution:def sumSubarrayMins(self, arr: List[int]) -> int:n len(arr)# 左边界 left[i] 为左侧严格小于 arr[i] 的最近元素位置&#xff08;不存在时为 -1&#xff09;left, s…

堆详解(C语言实现)

文章目录 写在前面1. 堆的概念和性质1.1 堆的概念1.2 堆的性质 2 堆的实现2.1 堆结构的定义2.2 堆的初始化2.3 堆的插入2.3.1 向上调整算法2.3.2 堆的插入元素过程 2.4 堆的删除2.4.1 向下调整算法2.4.2 堆的删除元素过程 2.5 获取堆顶元素2.6 获取堆元素个数2.7 判断堆是否为空…

C语言——打印出所有的“水仙花数”

所谓水仙花数,是指一个3位数,其各位数字立方和等于该数本身。水仙花数是指一个三位数&#xff0c;它的每个位上的数字的立方和等于它本身。例如&#xff0c;153是一个水仙花数&#xff0c;因为1^3 5^3 3^3 153。 #define _CRT_SECURE_NO_WARNINGS 1#include <stdio.h>…

【刷题笔记】分糖果||数组||暴力通过||符合思维方式||多案例分析

分发糖果 文章目录 分发糖果1 题目描述2 题目分析2.1 寻找波峰波谷2.2 从波底往波峰攀爬&#xff01;2.2 计算糖果 3 代码附录1 1 题目描述 https://leetcode.cn/problems/candy/ n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&…