vue3+ts封装图标选择组件

news/2024/5/20 4:36:17 标签: 开发语言, vue3, 图标选择器, ts

概要

讲解在vue3的项目中封装一个简单好用的图标选择组件。

效果

在这里插入图片描述

第一步,准备图标数据

数据太多,大家去项目中看。项目地址https://gitee.com/nideweixiaonuannuande/xt-admin-vue3
在这里插入图片描述

第二步,页面与样式编写

<template>
  <div>
    <el-icon
      class="icon-picker"
      :class="{ empty: myValue === '' }"
      @click="dialogVisible = true"
    >
      <svg-icon :name="myValue !== '' ? myValue : 'ep:plus'" />
    </el-icon>

    <xt-dialog v-model="dialogVisible" width="800px" title="选择图标" :show-cancel="false" :show-confirm="false">
      <div>
        <el-tabs v-model="activeName" tab-position="left">
          <el-tab-pane
            v-for="item in data"
            :key="item.prefix"
            :label="item.name"
            :name="item.prefix"
          >
            <div class="flex flex-wrap">
              <div
                class="border cursor-pointer border-red-300 p-4"
                title="删除已选图标"
                @click="removeIcon"
              >
                <el-icon :size="24">
                  <svg-icon name="ep:delete" />
                </el-icon>
              </div>
              <div
                v-for="icon in currentIconList"
                :key="icon"
                class="border cursor-pointer p-4"
                @click="chooseIcon(`${activeName}:${icon}`)"
              >
                <el-icon :size="24">
                  <svg-icon :name="`${activeName}:${icon}`" />
                </el-icon>
              </div>
            </div>
          </el-tab-pane>
        </el-tabs>
        <div class="flex mt-4 px-10 justify-end">
          <el-pagination
            v-model:current-page="pagination.page"
            layout="prev, pager, next"
            :page-size="pagination.pageSize"
            :total="iconList.length"
            :pager-count="5"
            background
          />
        </div>
      </div>
    </xt-dialog>
  </div>
</template>

<style lang="scss" scoped>
.icon-picker {
  width: 40px;
  height: 40px;
  line-height: 36px;
  text-align: center;
  color: var(--el-text-color-regular);
  border: 1px solid var(--el-border-color);
  border-radius: 5px;
  cursor: pointer;
  transition: 0.3s;
  font-size: 24px;
  vertical-align: middle;

  &:hover {
    border: 1px solid var(--el-border-color-darker);
  }

  &.empty {
    color: var(--el-text-color-placeholder);
    border: 1px dashed var(--el-border-color);

    &:hover {
      color: var(--el-text-color-regular);
      border: 1px solid var(--el-border-color-darker);
    }
  }
}
</style>

第三步,逻辑编写

<script setup lang="ts">
import data from './data/data.json'

defineOptions({
  name: 'IconPicker',
})

const props = withDefaults(defineProps<{
  modelValue: string
}>(), {})

const emits = defineEmits(['update:modelValue'])

const myValue = computed({
  get() {
    return props.modelValue
  },

  set(value) {
    emits('update:modelValue', value)
  },
})

// ------------------数据初始化------------------
const activeName = ref(myValue.value.split(':')[0] || data[0].prefix)

const pagination = ref({
  page: 1,
  pageSize: 49,
})
const iconList = computed(() => {
  return data.filter(item => item.prefix === activeName.value)[0].icons
})

const currentIconList = computed(() => {
  return iconList.value.slice(
    (pagination.value.page - 1) * pagination.value.pageSize,
    (pagination.value.page - 1) * pagination.value.pageSize
      + pagination.value.pageSize,
  )
})

// ------------------选择图标相关------------------
const dialogVisible = ref(false)

function chooseIcon(val: string) {
  myValue.value = val
  dialogVisible.value = false
}

function removeIcon() {
  myValue.value = ''
  dialogVisible.value = false
}
</script>

写在最后

vue3_159">这个组件中涉及到的svg-icon和xt-dialog组件大家可前往https://gitee.com/nideweixiaonuannuande/xt-admin-vue3中查看源代码


http://www.niftyadmin.cn/n/5147939.html

相关文章

AD1255/AD1256硬件SPI开发实战与跳坑过程

AD1255/AD1256硬件SPI开发实战与跳坑过程 以上图片我们可以知道在t17阶段&#xff0c;数据是不能被读取的。另外最小是16个τCLKIN&#xff0c;具体是多少这个跟你配置的DATA_rate的设置有关系。 1.6 同步SYNC的时序 要同步SYNC&#xff0c;要么采用管脚SYNC&#xff0c;要么…

[Hive] Map类型在表中是如何存储的

在 Hive 中&#xff0c;Map 类型是指键值对的集合&#xff0c;其中键和值都可以是任意数据类型。 在 Hive 表中&#xff0c;Map 类型通常被存储为结构体或者键值对列表。 具体来说&#xff0c;在表中&#xff0c;Map 类型通常分为以下两种存储方式&#xff1a; 文章目录 结构…

内网穿透实现远程访问,如何满足信息安全需求?

内网穿透技术是一种将内网服务映射到外网&#xff0c;从而实现远程访问的技术。它的出现为企业及个人带来了便利&#xff0c;但同时也带来了一定的安全风险。因此&#xff0c;确保内网穿透远程访问内网服务的安全性显得尤为重要。 贝锐旗下内网穿透兼动态域名解析品牌花生壳&am…

lazada商品评论API接口(评论内容|日期|买家昵称|追评内容|评论图片|评论视频..)

Lazada商品评论API接口是Lazada开放平台提供的一种API接口&#xff0c;可以帮助开发者获取Lazada平台上的商品评论数据。 通过该接口&#xff0c;开发者可以获取到用户对商品的评论信息&#xff0c;包括评论内容、评价等级、评论时间等&#xff0c;从而了解用户对商品的反馈和…

使用Navicat访问宝塔中的MySQL数据库

首先放开数据库权限 然后放开3306端口 数据库默认端口是3306&#xff0c;如果改了&#xff0c;这里就填改的那个端口 连接数据库 复制数据库用户名和密码 填入Navicat中&#xff0c;主机只需要填IP即可 连接成功

Tomcat为什么支持线程池?

Tomcat作为一个Java Servlet容器&#xff0c;支持线程池是因为它能够处理多个并发请求。这些请求可以是对Web应用程序的HTTP请求、Servlet的请求&#xff0c;或其他支持的协议。 支持线程池的主要原因包括&#xff1a; 并发处理能力&#xff1a; 提高性能&#xff1a; 使用线程…

Qt 表格QTableWidget

表格是Qt最重量级的控件之一&#xff0c;另外一个重量级控件就是树。QTableWidget是成熟的表格控件&#xff0c;它有默认的模型QTableModel&#xff08;继承自QAbstractTableModel&#xff09;&#xff0c;QTableWidget本身继承自QTableView。 本文通过多个示例展示QTableWidg…

【UI小图标带UIShiny流光效果,永远在3D物体最前面渲染,UI层级显示在最上层】

UI小图标带UIShiny流光效果,永远在3D物体最前面渲染,UI层级显示在最上层 需求描述1. 实现UI流光下载链接如下:如下图:UI-Front-Shiny.shader代码如下:文字层级在最上层的Shader代码如下:最终效果如下:需求描述 UI层,实现流光效果。UI层级在最上层,在场景任何3D物体前…