news 2026/2/8 14:39:11

封装ElementPlusIcons图标和系统应用内置图片为应用图标

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
封装ElementPlusIcons图标和系统应用内置图片为应用图标

效果图:

文件放置位置结构

1、定义选择按钮父组件 icon

<template> <div> <iconEdit :mode="'button'" /> </div> </template> <script lang="ts" setup> import iconEdit from "../../components/IconEdit/indev.vue"; </script> <style scoped lang="scss"></style>

2、IconEdit组件

<template> <div> <div v-if="mode === 'button'" class="button-container"> <IconComp v-if="icon" :icon="icon" /> <el-button link type="primary" @click="openIcon"> 选择图片 </el-button> </div> <el-dialog v-model="iconVisible" title="选择图标" width="900" draggable :close-on-click-modal="false"> <el-tabs v-model="activeName" class="icons-tabs"> <el-tab-pane label="内置图标" name="icon"> <div class="button-container"> <el-input v-model="search" :suffix-icon="Search" placeholder="请输入关键字搜索图标" style="width: 240px" @input="searchAction(search)" /> <el-input v-model="colorInput" style="width: 120px" placeholder="颜色"> <template #suffix> <input ref="iconPick" type="color" v-model="colorInput" class="w-[26px]" /> </template> </el-input> </div> <div class="icons-container mt-3 h-[350px] overflow-y-auto"> <el-row :gutter="20"> <el-col v-for="(item, index) in elementPlusIcons" :key="index" :span="2" class="mb-1 cursor-pointer" @click="selectAction(item.name)" > <div :class="{ 'selected-icon': item.name === selected }"> <component :is="item" v-bind="$attrs" :style="{ color: colorInput }" /> <p class="icons-text text-center">{{ item.name }}</p> </div> </el-col> </el-row> </div> </el-tab-pane> <el-tab-pane label="系统内置图片" name="icon-preset"> <el-input v-model="search" :suffix-icon="Search" placeholder="请输入关键字搜索图片" style="width: 240px" @input="searchAction(search)" /> <div class="icons-container mt-3 h-[350px] overflow-y-auto"> <el-row :gutter="20"> <el-col v-for="(item, index) in systemIcons" :key="index" :span="2" class="mb-1 cursor-pointer" @click="selectAction(item.code)" > <div style="display: flex; align-items: center; flex-direction: column" :class="{ 'selected-icon': item.code === selected }" > <img style="width: 50px; height: 50px" :src="item.icon" /> <p class="icons-text text-center">{{ item.name }}</p> </div> </el-col> </el-row> </div> </el-tab-pane> </el-tabs> <template #footer> <div class="dialog-footer"> <el-button @click="reset">重置</el-button> <el-button @click="iconVisible = false">取消</el-button> <el-button type="primary" @click="handleConfirm()"> 确定 </el-button> </div> </template> </el-dialog> </div> </template> <script lang="ts" setup> import { type Component, ref, shallowRef, watch, nextTick } from "vue"; import IconComp from "../../components/IconEdit/iconComp.vue"; import { Icons, AiIcons } from "../../assets/index"; import { Search } from "@element-plus/icons-vue"; import * as ElementPlusIcons from "@element-plus/icons-vue"; const props = defineProps<{ mode?: string; isReadonly?: boolean; }>(); /** 数据源, 父组件不能为空,默认'' */ const icon = defineModel("icon", { type: String, default: "", }); const emit = defineEmits(["confirm", "typeConfirm"]); const activeName = ref("icon"); const iconComp = shallowRef<Component>(); const search = ref(""); const colorInput = ref(""); const selected = ref<string>(""); const systemIcons = ref<any[]>([...Icons, ...AiIcons]); // 打开模态框 const iconVisible = ref(false); const iconPick = ref(); // 打开弹窗 const openIcon = () => { iconVisible.value = true; search.value = ""; const iconArray = icon.value.split("#"); iconComp.value = ElementPlusIcons[iconArray[0] as keyof typeof ElementPlusIcons]; if (iconComp.value) { selected.value = iconArray[0]; colorInput.value = iconArray[1] ? `#${iconArray[1]}` : ""; nextTick(() => { iconPick.value.value = colorInput.value; }); } searchAction(""); }; // 关闭弹窗 const closeIcon = () => { iconVisible.value = false; }; const elementPlusIcons = shallowRef<any>(ElementPlusIcons); const reset = () => { selected.value = ""; iconComp.value = undefined; colorInput.value = ""; iconPick.value.value = ""; }; // 搜索图标 const searchAction = (keyWord: string) => { if (keyWord === "") { elementPlusIcons.value = ElementPlusIcons; return; } const filterIcons = Object.keys(ElementPlusIcons).filter((item) => { return item.toLowerCase().includes(keyWord.toLowerCase()); }); elementPlusIcons.value = {}; filterIcons.forEach((item) => { elementPlusIcons.value[item] = ElementPlusIcons[item as keyof typeof ElementPlusIcons]; }); }; const selectAction = (item: string) => { selected.value = item; }; // 确定图标 const handleConfirm = () => { icon.value = activeName.value === "icon" && colorInput.value ? selected.value + colorInput.value : selected.value; emit("confirm", icon.value); emit("typeConfirm", { type: activeName, value: icon.value, }); iconVisible.value = false; }; watch( () => icon.value, (newValue) => { if (newValue) { const iconArray = newValue.split("#"); iconComp.value = ElementPlusIcons[iconArray[0] as keyof typeof ElementPlusIcons]; if (iconComp.value) { selected.value = iconArray[0]; colorInput.value = iconArray[1]; nextTick(() => { if (iconPick.value) iconPick.value.value = colorInput.value ? `#${colorInput.value}` : ""; }); } } else { selected.value = ""; iconComp.value = undefined; colorInput.value = ""; } }, { immediate: true, } ); // 暴露方法· defineExpose({ closeIcon, openIcon, }); </script> <style scoped lang="scss"> .icons-tabs { .icons-container { padding-right: 15px; margin-right: -10px; } } .selected-icon { background-color: #409eff; border-radius: 6px; } .icons-text { font-size: 12px; } .button-container { display: flex; gap: 0.5rem; /* 2对应大约0.5rem(8px) */ } </style>

3、iconComp组件

<template> <div> <component v-if="iconComp" :is="iconComp" :style="{ color: icon?.split('#')[1], width: size + 'px', height: size + 'px' }" /> <img v-else-if="systemIcons?.find((f: any) => f.code == icon)" :style="{ width: size + 'px', height: size + 'px' }" :src="systemIcons?.find((f: any) => f.code == icon)?.icon" /> <div v-else-if="icon" class="form-icon-item" v-html="icon"></div> </div> </template> <script setup lang="ts"> import { watch, shallowRef, type Component } from "vue"; import * as ElementPlusIcons from "@element-plus/icons-vue"; import { AiIcons, Icons } from "../../assets/index"; const props = defineProps({ icon: { type: String, default: () => {}, }, size: { type: Number, default: 16, }, }); const systemIcons = [...Icons, ...AiIcons]; const iconComp = shallowRef<Component>(); watch( () => props.icon, (newValue) => { if (newValue) { const iconArray = newValue.split("#"); iconComp.value = ElementPlusIcons[iconArray[0] as keyof typeof ElementPlusIcons]; } }, { immediate: true, } ); </script> <style lang="less" scoped></style>

4、系统内置图片路径

index.ts

import bbmbSrc from "../assets/aiToolsIcons/baobiaomoban.png"; import aizy from "../assets/aiToolsIcons/ocr-yinshuawenzishibie.png"; import wbrs from "../assets/aiToolsIcons/wenbenbianjitianchong.png"; import dybgzx from "../assets/aiToolsIcons/baogao.png"; import dyjhzd from "../assets/aiToolsIcons/jihua.png"; import wzsb from "../assets/aiToolsIcons/ocr-yinshuawenzishibie.png"; import wdxxtq from "../assets/aiToolsIcons/wendang.png"; import pzsb from "../assets/aiToolsIcons/chuanpiaozhengfuwu.png"; import wdzh from "../assets/aiToolsIcons/zhuanhuan.png"; import wjcfhb from "../assets/aiToolsIcons/picichaifenhebing.png"; import yywbsc from "../assets/aiToolsIcons/zhihuiyuyinwenben.png"; import hgxjc from "../assets/aiToolsIcons/hefahegui.png"; import bgzdhsc from "../assets/aiToolsIcons/baobiaomoban.png"; import hyjysc from "../assets/aiToolsIcons/huiyi.png"; import wzzyy from "../assets/aiToolsIcons/zhihuiyuyinwenben.png"; import csznzs from "../assets/aiToolsIcons/测试智能助手.png"; import flfg from "../assets/aiToolsIcons/法律法规.png"; import fgk from "../assets/aiToolsIcons/法规库.png"; import flfgk from "../assets/aiToolsIcons/法律法规库@2x.png"; import nbzdk from "../assets/aiToolsIcons/内部制度库.png"; import rdjdzs from "../assets/aiToolsIcons/人大监督助手@2x.png"; import sjfxjmzs from "../assets/aiToolsIcons/审计分析建模助手.png"; import sjjdzs from "../assets/aiToolsIcons/审计监督助手@2x.png"; import sjwtdxzs from "../assets/aiToolsIcons/审计问题定性助手.png"; import sjywtjzs from "../assets/aiToolsIcons/审计业务推荐助手.png"; import sjzgzyzs from "../assets/aiToolsIcons/审计整改指引助手.png"; import xzyszt from "../assets/aiToolsIcons/新增预设主题.png"; import zbdbfxznzs from "../assets/aiToolsIcons/招标对比分析智能助手.png"; import zmzcfxzs from "../assets/aiToolsIcons/中煤招采分析助手.png"; import zdytsc from "../assets/aiToolsIcons/自定义提示词@2x.png"; import aiyyzs from "../assets/aiToolsIcons/AI应用助手@2x.png"; import bijcfxzs from "../assets/aiToolsIcons/BI集成分析助手.png"; export * from './aiIcons/index'; export const Icons = [ { name: '标签模板', code: 'system-bbmbSrc', icon: bbmbSrc }, { name: '文字识别', code: 'system-aizy', icon: aizy }, { name: '文本编辑', code: 'system-wbrs', icon: wbrs }, { name: '报告', code: 'system-dybgzx', icon: dybgzx }, { name: '计划', code: 'system-dyjhzd', icon: dyjhzd }, { name: '识别', code: 'system-wzsb', icon: wzsb }, { name: '文档', code: 'system-wdxxtq', icon: wdxxtq }, { name: '传票', code: 'system-pzsb', icon: pzsb }, { name: '转换', code: 'system-wdzh', icon: wdzh }, { name: '拆分', code: 'system-wjcfhb', icon: wjcfhb }, { name: '语音', code: 'system-yywbsc', icon: yywbsc }, { name: '合法合规', code: 'system-hgxjc', icon: hgxjc }, { name: '报表模板', code: 'system-bgzdhsc', icon: bgzdhsc }, { name: '会议', code: 'system-hyjysc', icon: hyjysc }, { name: '语音文本', code: 'system-wzzyy', icon: wzzyy }, { name: '测试智能助手', code: 'system-csznzs', icon: csznzs }, { name: '法律法规', code: 'system-flfg', icon: flfg }, { name: '法规库', code: 'system-fgk', icon: fgk }, { name: '法律法规库', code: 'system-flfgk', icon: flfgk }, { name: '内部制度库', code: 'system-nbzdk', icon: nbzdk }, { name: '人大监督助手', code: 'system-rdjdzs', icon: rdjdzs }, { name: '审计分析建模助手', code: 'system-sjfxjmzs', icon: sjfxjmzs }, { name: '审计监督助手', code: 'system-sjjdzs', icon: sjjdzs }, { name: '审计问题定性助手', code: 'system-sjwtdxzs', icon: sjwtdxzs }, { name: '审计业务推荐助手', code: 'system-sjywtjzs', icon: sjywtjzs }, { name: '审计整改指引助手', code: 'system-sjzgzyzs', icon: sjzgzyzs }, { name: '新增预设主题', code: 'system-xzyszt', icon: xzyszt }, { name: '招标对比分析智能助手', code: 'system-zbdbfxznzs', icon: zbdbfxznzs }, { name: '中煤招采分析助手', code: 'system-zmzcfxzs', icon: zmzcfxzs }, { name: '自定义提示词', code: 'system-zdytsc', icon: zdytsc }, { name: 'AI应用助手', code: 'system-aiyyzs', icon: aiyyzs }, { name: 'BI集成分析助手', code: 'system-bijcfxzs', icon: bijcfxzs }, ]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!