浏览代码

perf: 将本地图标全部按需引入,首屏加载减少 `61` 个图标资源,首屏加载再次变快 (#389)

* perf: 优化图标,将本地图标按需引入,首屏加载减少 `61` 个图标资源,首屏加载再次变快
RealityBoy 2 年之前
父节点
当前提交
c7ab236e10
共有 63 个文件被更改,包括 782 次插入659 次删除
  1. 14 1
      build/optimize.ts
  2. 15 7
      mock/asyncRoutes.ts
  3. 0 5
      package.json
  4. 460 321
      pnpm-lock.yaml
  5. 13 0
      src/components/ReIcon/src/hooks.ts
  6. 3 173
      src/components/ReIcon/src/iconifyIconOffline.ts
  7. 2 1
      src/components/ReQrcode/src/index.tsx
  8. 10 4
      src/components/ReTable/src/bar.tsx
  9. 7 4
      src/layout/components/navbar.vue
  10. 2 1
      src/layout/components/notice/index.vue
  11. 2 1
      src/layout/components/panel/index.vue
  12. 4 2
      src/layout/components/search/components/SearchFooter.vue
  13. 2 1
      src/layout/components/search/components/SearchModal.vue
  14. 2 1
      src/layout/components/search/components/SearchResult.vue
  15. 3 1
      src/layout/components/search/index.vue
  16. 4 2
      src/layout/components/setting/index.vue
  17. 7 4
      src/layout/components/sidebar/horizontal.vue
  18. 3 1
      src/layout/components/sidebar/leftCollapse.vue
  19. 7 4
      src/layout/components/sidebar/mixNav.vue
  20. 13 5
      src/layout/components/sidebar/sidebarItem.vue
  21. 4 1
      src/layout/components/sidebar/topCollapse.vue
  22. 15 11
      src/layout/components/tag/index.vue
  23. 16 8
      src/layout/hooks/useTag.ts
  24. 6 3
      src/layout/types.ts
  25. 2 1
      src/router/modules/able.ts
  26. 0 1
      src/router/modules/about.ts
  27. 2 1
      src/router/modules/components.ts
  28. 2 1
      src/router/modules/editor.ts
  29. 2 1
      src/router/modules/error.ts
  30. 2 1
      src/router/modules/flowchart.ts
  31. 3 1
      src/router/modules/formdesign.ts
  32. 2 1
      src/router/modules/guide.ts
  33. 2 1
      src/router/modules/home.ts
  34. 4 2
      src/router/modules/list.ts
  35. 2 1
      src/router/modules/nested.ts
  36. 2 1
      src/router/modules/ppt.ts
  37. 2 1
      src/router/modules/remaining.ts
  38. 2 1
      src/router/modules/result.ts
  39. 0 8
      src/style/reset.scss
  40. 2 1
      src/views/able/menu-tree.vue
  41. 2 1
      src/views/able/timeline.vue
  42. 2 1
      src/views/components/draggable/index.vue
  43. 2 1
      src/views/components/message/index.vue
  44. 2 1
      src/views/components/video/index.vue
  45. 2 1
      src/views/editor/index.vue
  46. 3 1
      src/views/flow-chart/index.vue
  47. 2 1
      src/views/list/card/components/Card.vue
  48. 7 2
      src/views/list/card/index.vue
  49. 2 1
      src/views/login/components/phone.vue
  50. 7 4
      src/views/login/components/regist.vue
  51. 5 3
      src/views/login/components/update.vue
  52. 6 4
      src/views/login/index.vue
  53. 4 2
      src/views/pure-table/high/edit/columns.tsx
  54. 6 4
      src/views/result/columns.tsx
  55. 10 5
      src/views/system/dept/index.vue
  56. 4 2
      src/views/system/dict/config.vue
  57. 4 2
      src/views/system/dict/index.vue
  58. 16 8
      src/views/system/role/index.vue
  59. 17 11
      src/views/system/user/index.vue
  60. 17 8
      src/views/system/user/tree.vue
  61. 12 6
      src/views/welcome/components/columns.tsx
  62. 3 2
      types/global.d.ts
  63. 2 2
      vite.config.ts

+ 14 - 1
build/optimize.ts

@@ -4,7 +4,7 @@
  * 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里,否则会遇到开发环境切换页面卡顿的问题(vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
  * 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
  */
-export const include = [
+const include = [
   "qs",
   "mitt",
   "xlsx",
@@ -50,3 +50,16 @@ export const include = [
   "xgplayer/es/controls/screenShot",
   "xgplayer/es/controls/playbackRate"
 ];
+
+/**
+ * 在预构建中强制排除的依赖项
+ * 温馨提示:所有以 `@iconify-icons/` 开头引入的的本地图标模块,都应该加入到下面的 `exclude` 里,因为平台推荐的使用方式是哪里需要哪里引入而且都是单个的引入,不需要预构建,直接让浏览器加载就好
+ */
+const exclude = [
+  "@iconify-icons/ep",
+  "@iconify-icons/ri",
+  "@iconify-icons/mdi",
+  "@pureadmin/theme/dist/browser-utils"
+];
+
+export { include, exclude };

+ 15 - 7
mock/asyncRoutes.ts

@@ -2,6 +2,14 @@
 import { MockMethod } from "vite-plugin-mock";
 import { system, permission, frame, tabs } from "@/router/enums";
 
+import FlUser from "@iconify-icons/ri/admin-line";
+import Role from "@iconify-icons/ri/admin-fill";
+import Dict from "@iconify-icons/ri/git-repository-line";
+import Setting from "@iconify-icons/ri/settings-3-line";
+import Dept from "@iconify-icons/ri/git-branch-line";
+import Lollipop from "@iconify-icons/ep/lollipop";
+import Monitor from "@iconify-icons/ep/monitor";
+
 /**
  * roles:页面级别权限,这里模拟二种 "admin"、"common"
  * admin:管理员角色
@@ -11,7 +19,7 @@ import { system, permission, frame, tabs } from "@/router/enums";
 const systemRouter = {
   path: "/system",
   meta: {
-    icon: "setting",
+    icon: Setting,
     title: "menus.hssysManagement",
     rank: system
   },
@@ -20,7 +28,7 @@ const systemRouter = {
       path: "/system/user/index",
       name: "User",
       meta: {
-        icon: "flUser",
+        icon: FlUser,
         title: "menus.hsUser",
         roles: ["admin"]
       }
@@ -29,7 +37,7 @@ const systemRouter = {
       path: "/system/role/index",
       name: "Role",
       meta: {
-        icon: "role",
+        icon: Role,
         title: "menus.hsRole",
         roles: ["admin"]
       }
@@ -38,7 +46,7 @@ const systemRouter = {
       path: "/system/dept/index",
       name: "Dept",
       meta: {
-        icon: "dept",
+        icon: Dept,
         title: "menus.hsDept",
         roles: ["admin"]
       }
@@ -48,7 +56,7 @@ const systemRouter = {
       component: "/system/dict/index",
       name: "Dict",
       meta: {
-        icon: "dict",
+        icon: Dict,
         title: "menus.hsDict",
         keepAlive: true,
         roles: ["admin"]
@@ -61,7 +69,7 @@ const permissionRouter = {
   path: "/permission",
   meta: {
     title: "menus.permission",
-    icon: "lollipop",
+    icon: Lollipop,
     rank: permission
   },
   children: [
@@ -88,7 +96,7 @@ const permissionRouter = {
 const frameRouter = {
   path: "/iframe",
   meta: {
-    icon: "monitor",
+    icon: Monitor,
     title: "menus.hsExternalPage",
     rank: frame
   },

+ 0 - 5
package.json

@@ -86,14 +86,9 @@
   "devDependencies": {
     "@commitlint/cli": "13.1.0",
     "@commitlint/config-conventional": "13.1.0",
-    "@iconify-icons/carbon": "^1.2.8",
     "@iconify-icons/ep": "^1.2.7",
-    "@iconify-icons/fa": "^1.2.3",
-    "@iconify-icons/fa-solid": "^1.2.3",
-    "@iconify-icons/fluent": "^1.2.16",
     "@iconify-icons/mdi": "^1.2.8",
     "@iconify-icons/ri": "^1.2.3",
-    "@iconify-icons/uil": "^1.2.2",
     "@iconify/vue": "^4.0.0",
     "@intlify/vite-plugin-vue-i18n": "^6.0.3",
     "@pureadmin/theme": "^2.4.0",

文件差异内容过多而无法显示
+ 460 - 321
pnpm-lock.yaml


+ 13 - 0
src/components/ReIcon/src/hooks.ts

@@ -1,5 +1,6 @@
 import { iconType } from "./types";
 import { h, defineComponent, Component } from "vue";
+import { addIcon } from "@iconify/vue/dist/offline";
 import { IconifyIconOnline, IconifyIconOffline, FontIcon } from "../index";
 
 /**
@@ -34,6 +35,18 @@ export function useRenderIcon(icon: any, attrs?: iconType): Component {
   } else if (typeof icon === "function" || typeof icon?.render === "function") {
     // svg
     return icon;
+  } else if (typeof icon === "object") {
+    // iconify 本地图标
+    addIcon(icon, icon);
+    return defineComponent({
+      name: "OfflineIcon",
+      render() {
+        return h(IconifyIconOffline, {
+          icon: icon,
+          ...attrs
+        });
+      }
+    });
   } else {
     // 通过是否存在 : 符号来判断是在线还是本地图标,存在即是在线图标,反之
     return defineComponent({

+ 3 - 173
src/components/ReIcon/src/iconifyIconOffline.ts

@@ -1,192 +1,22 @@
 import { h, defineComponent } from "vue";
 import { Icon as IconifyIcon, addIcon } from "@iconify/vue/dist/offline";
 
-// element-plus icon
-import Check from "@iconify-icons/ep/check";
-import Menu from "@iconify-icons/ep/menu";
-import HomeFilled from "@iconify-icons/ep/home-filled";
-import SetUp from "@iconify-icons/ep/set-up";
-import Edit from "@iconify-icons/ep/edit";
-import Lollipop from "@iconify-icons/ep/lollipop";
-import Link from "@iconify-icons/ep/link";
-import Position from "@iconify-icons/ep/position";
-import Histogram from "@iconify-icons/ep/histogram";
-import RefreshRight from "@iconify-icons/ep/refresh-right";
-import Close from "@iconify-icons/ep/close";
-import CloseBold from "@iconify-icons/ep/close-bold";
-import Bell from "@iconify-icons/ep/bell";
-import Guide from "@iconify-icons/ep/guide";
-import Iphone from "@iconify-icons/ep/iphone";
-import Location from "@iconify-icons/ep/location";
-import Tickets from "@iconify-icons/ep/tickets";
-import OfficeBuilding from "@iconify-icons/ep/office-building";
-import Notebook from "@iconify-icons/ep/notebook";
-import Rank from "@iconify-icons/ep/rank";
-import VideoPlay from "@iconify-icons/ep/video-play";
-import Monitor from "@iconify-icons/ep/monitor";
-import Search from "@iconify-icons/ep/search";
-import Refresh from "@iconify-icons/ep/refresh";
-import EditPen from "@iconify-icons/ep/edit-pen";
-import Delete from "@iconify-icons/ep/delete";
-import More from "@iconify-icons/ep/more-filled";
-import EpArrowDown from "@iconify-icons/ep/arrow-down";
-import ArrowUp from "@iconify-icons/ep/arrow-up";
-import ArrowRight from "@iconify-icons/ep/arrow-right";
-import ArrowLeft from "@iconify-icons/ep/arrow-left";
-addIcon("check", Check);
-addIcon("menu", Menu);
-addIcon("home-filled", HomeFilled);
-addIcon("set-up", SetUp);
-addIcon("edit", Edit);
-addIcon("lollipop", Lollipop);
-addIcon("link", Link);
-addIcon("position", Position);
-addIcon("histogram", Histogram);
-addIcon("refresh-right", RefreshRight);
-addIcon("close", Close);
-addIcon("close-bold", CloseBold);
-addIcon("bell", Bell);
-addIcon("guide", Guide);
-addIcon("iphone", Iphone);
-addIcon("location", Location);
-addIcon("tickets", Tickets);
-addIcon("office-building", OfficeBuilding);
-addIcon("notebook", Notebook);
-addIcon("video-play", VideoPlay);
-addIcon("rank", Rank);
-addIcon("monitor", Monitor);
-addIcon("search", Search);
-addIcon("refresh", Refresh);
-addIcon("edits", EditPen);
-addIcon("delete", Delete);
-addIcon("more", More);
-addIcon("ep-arrow-down", EpArrowDown);
-addIcon("ep-arrow-up", ArrowUp);
-addIcon("ep-arrow-right", ArrowRight);
-addIcon("ep-arrow-left", ArrowLeft);
-
-// remixicon
-import ArrowRightSLine from "@iconify-icons/ri/arrow-right-s-line";
-import ArrowLeftSLine from "@iconify-icons/ri/arrow-left-s-line";
-import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
-import NodeTree from "@iconify-icons/ri/node-tree";
-import UbuntuFill from "@iconify-icons/ri/ubuntu-fill";
-import QuestionLine from "@iconify-icons/ri/question-line";
-import CheckboxCircleLine from "@iconify-icons/ri/checkbox-circle-line";
-import InformationLine from "@iconify-icons/ri/information-line";
-import CloseCircleLine from "@iconify-icons/ri/close-circle-line";
-import ArrowUpLine from "@iconify-icons/ri/arrow-up-line";
-import ArrowDownLine from "@iconify-icons/ri/arrow-down-line";
-import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line";
-import AddFill from "@iconify-icons/ri/add-circle-line";
-import AddLine from "@iconify-icons/ri/add-line";
-import ListCheck from "@iconify-icons/ri/list-check";
-import More2Fill from "@iconify-icons/ri/more-2-fill";
-import Database from "@iconify-icons/ri/database-2-line";
-import Dict from "@iconify-icons/ri/git-repository-line";
-import Card from "@iconify-icons/ri/bank-card-line";
-import Reset from "@iconify-icons/ri/restart-line";
-import Dept from "@iconify-icons/ri/git-branch-line";
-import Password from "@iconify-icons/ri/lock-password-line";
-import Ppt from "@iconify-icons/ri/file-ppt-2-line";
-import TerminalWindowLine from "@iconify-icons/ri/terminal-window-line";
-import User from "@iconify-icons/ri/user-3-fill";
-import Lock from "@iconify-icons/ri/lock-fill";
-import MenuUnfold from "@iconify-icons/ri/menu-unfold-fill";
-import MenuFold from "@iconify-icons/ri/menu-fold-fill";
-import Setting from "@iconify-icons/ri/settings-3-line";
-import ArrowDown from "@iconify-icons/ri/arrow-down-s-line";
-import CloseLeftTags from "@iconify-icons/ri/text-direction-r";
-import CloseRightTags from "@iconify-icons/ri/text-direction-l";
-import CloseOtherTags from "@iconify-icons/ri/text-spacing";
-import CloseAllTags from "@iconify-icons/ri/subtract-line";
-import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
-import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
-addIcon("arrow-right-s-line", ArrowRightSLine);
-addIcon("arrow-left-s-line", ArrowLeftSLine);
-addIcon("logout-circle-r-line", LogoutCircleRLine);
-addIcon("node-tree", NodeTree);
-addIcon("ubuntu-fill", UbuntuFill);
-addIcon("question-line", QuestionLine);
-addIcon("checkbox-circle-line", CheckboxCircleLine);
-addIcon("information-line", InformationLine);
-addIcon("close-circle-line", CloseCircleLine);
-addIcon("arrow-up-line", ArrowUpLine);
-addIcon("arrow-down-line", ArrowDownLine);
-addIcon("bookmark-2-line", Bookmark2Line);
-addIcon("add", AddFill);
-addIcon("add-line", AddLine);
-addIcon("list-check", ListCheck);
-addIcon("more-vertical", More2Fill);
-addIcon("database", Database);
-addIcon("dict", Dict);
-addIcon("card", Card);
-addIcon("reset", Reset);
-addIcon("dept", Dept);
-addIcon("password", Password);
-addIcon("ppt", Ppt);
-addIcon("terminal-window-line", TerminalWindowLine);
-addIcon("user", User);
-addIcon("lock", Lock);
-addIcon("menu-unfold", MenuUnfold);
-addIcon("menu-fold", MenuFold);
-addIcon("setting", Setting);
-addIcon("arrow-down", ArrowDown);
-addIcon("close-left-tags", CloseLeftTags);
-addIcon("close-right-tags", CloseRightTags);
-addIcon("close-other-tags", CloseOtherTags);
-addIcon("close-all-tags", CloseAllTags);
-addIcon("fullscreen", Fullscreen);
-addIcon("exit-fullscreen", ExitFullscreen);
-
-// Font Awesome 4
-import FaUser from "@iconify-icons/fa/user";
-import FaLock from "@iconify-icons/fa/lock";
-import FaSignOut from "@iconify-icons/fa/sign-out";
-addIcon("fa-user", FaUser);
-addIcon("fa-lock", FaLock);
-addIcon("fa-sign-out", FaSignOut);
-
-// Unicons
-import Import from "@iconify-icons/uil/import";
-import Export from "@iconify-icons/uil/export";
-import ArrowsShrinkV from "@iconify-icons/uil/arrows-shrink-v";
-addIcon("import", Import);
-addIcon("export", Export);
-addIcon("density", ArrowsShrinkV);
-
-// fluent
-import Role from "@iconify-icons/fluent/people-swap-28-filled";
-import FlUser from "@iconify-icons/fluent/person-12-filled";
-addIcon("role", Role);
-addIcon("flUser", FlUser);
-
-// Material Design Icons
-import Expand from "@iconify-icons/mdi/arrow-expand-down";
-import UnExpand from "@iconify-icons/mdi/arrow-expand-right";
-addIcon("expand", Expand);
-addIcon("unExpand", UnExpand);
-
-// carbon
-import LocationCompany from "@iconify-icons/carbon/location-company";
-addIcon("location-company", LocationCompany);
-
 // Iconify Icon在Vue里本地使用(用于内网环境)https://docs.iconify.design/icon-components/vue/offline.html
 export default defineComponent({
   name: "IconifyIconOffline",
   components: { IconifyIcon },
   props: {
     icon: {
-      type: String,
-      default: ""
+      default: null
     }
   },
   render() {
+    if (typeof this.icon === "object") addIcon(this.icon, this.icon);
     const attrs = this.$attrs;
     return h(
       IconifyIcon,
       {
-        icon: `${this.icon}`,
+        icon: this.icon,
         style: attrs?.style
           ? Object.assign(attrs.style, { outline: "none" })
           : { outline: "none" },

+ 2 - 1
src/components/ReQrcode/src/index.tsx

@@ -13,6 +13,7 @@ import { isString } from "@pureadmin/utils";
 import { propTypes } from "@/utils/propTypes";
 import { IconifyIconOffline } from "../../ReIcon";
 import QRCode, { QRCodeRenderersOptions } from "qrcode";
+import RefreshRight from "@iconify-icons/ep/refresh-right";
 
 interface QrcodeLogo {
   src?: string;
@@ -247,7 +248,7 @@ export default defineComponent({
               <div class="absolute top-[50%] left-[50%] font-bold">
                 <IconifyIconOffline
                   class="cursor-pointer"
-                  icon="refresh-right"
+                  icon={RefreshRight}
                   width="30"
                   color="var(--el-color-primary)"
                 />

+ 10 - 4
src/components/ReTable/src/bar.tsx

@@ -1,6 +1,12 @@
 import { defineComponent, ref, computed, PropType } from "vue";
 import { useEpThemeStoreHook } from "@/store/modules/epTheme";
+
+import UnExpand from "@iconify-icons/mdi/arrow-expand-right";
 import { IconifyIconOffline } from "../../ReIcon";
+import Expand from "@iconify-icons/mdi/arrow-expand-down";
+import ArrowCollapse from "@iconify-icons/mdi/arrow-collapse-vertical";
+import Setting from "@iconify-icons/ri/settings-3-line";
+import RefreshRight from "@iconify-icons/ep/refresh-right";
 
 export const loadingSvg = `
   <path class="path" d="
@@ -105,7 +111,7 @@ export default defineComponent({
       reference: () => (
         <IconifyIconOffline
           class="cursor-pointer"
-          icon="setting"
+          icon={Setting}
           width="16"
           color="text_color_regular"
           onMouseover={e => (buttonRef.value = e.currentTarget)}
@@ -135,7 +141,7 @@ export default defineComponent({
                   >
                     <IconifyIconOffline
                       class="cursor-pointer"
-                      icon={isExpandAll.value ? "unExpand" : "expand"}
+                      icon={isExpandAll.value ? UnExpand : Expand}
                       width="16"
                       color="text_color_regular"
                       onClick={() => onExpand()}
@@ -147,7 +153,7 @@ export default defineComponent({
               <el-tooltip effect="dark" content="刷新" placement="top">
                 <IconifyIconOffline
                   class="cursor-pointer"
-                  icon="refresh-right"
+                  icon={RefreshRight}
                   width="16"
                   color="text_color_regular"
                   onClick={() => emit("refresh")}
@@ -159,7 +165,7 @@ export default defineComponent({
                 <el-dropdown v-slots={dropdown} trigger="click">
                   <IconifyIconOffline
                     class="cursor-pointer"
-                    icon="density"
+                    icon={ArrowCollapse}
                     width="16"
                     color="text_color_regular"
                   />

+ 7 - 4
src/layout/components/navbar.vue

@@ -7,6 +7,9 @@ import Breadcrumb from "./sidebar/breadCrumb.vue";
 import topCollapse from "./sidebar/topCollapse.vue";
 import { useTranslationLang } from "../hooks/useTranslationLang";
 import globalization from "@/assets/svg/globalization.svg?component";
+import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
+import Setting from "@iconify-icons/ri/settings-3-line";
+import Check from "@iconify-icons/ep/check";
 
 const {
   layout,
@@ -62,7 +65,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
               <IconifyIconOffline
                 class="check-zh"
                 v-show="locale === 'zh'"
-                icon="check"
+                :icon="Check"
               />
               简体中文
             </el-dropdown-item>
@@ -72,7 +75,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
               @click="translationEn"
             >
               <span class="check-en" v-show="locale === 'en'">
-                <IconifyIconOffline icon="check" />
+                <IconifyIconOffline :icon="Check" />
               </span>
               English
             </el-dropdown-item>
@@ -92,7 +95,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
           <el-dropdown-menu class="logout">
             <el-dropdown-item @click="logout">
               <IconifyIconOffline
-                icon="logout-circle-r-line"
+                :icon="LogoutCircleRLine"
                 style="margin: 5px"
               />
               {{ t("buttons.hsLoginOut") }}
@@ -105,7 +108,7 @@ const { t, locale, translationCh, translationEn } = useTranslationLang();
         :title="t('buttons.hssystemSet')"
         @click="onPanel"
       >
-        <IconifyIconOffline icon="setting" />
+        <IconifyIconOffline :icon="Setting" />
       </span>
     </div>
   </div>

+ 2 - 1
src/layout/components/notice/index.vue

@@ -2,6 +2,7 @@
 import { ref } from "vue";
 import { noticesData } from "./data";
 import NoticeList from "./noticeList.vue";
+import Bell from "@iconify-icons/ep/bell";
 
 const noticesNum = ref(0);
 const notices = ref(noticesData);
@@ -15,7 +16,7 @@ notices.value.map(v => (noticesNum.value += v.list.length));
     <span class="dropdown-badge navbar-bg-hover select-none">
       <el-badge :value="noticesNum" :max="99">
         <span class="header-notice-icon">
-          <IconifyIconOffline icon="bell" />
+          <IconifyIconOffline :icon="Bell" />
         </span>
       </el-badge>
     </span>

+ 2 - 1
src/layout/components/panel/index.vue

@@ -2,6 +2,7 @@
 import { ref } from "vue";
 import { onClickOutside } from "@vueuse/core";
 import { emitter } from "@/utils/mitt";
+import Close from "@iconify-icons/ep/close";
 
 const show = ref<Boolean>(false);
 const target = ref(null);
@@ -25,7 +26,7 @@ emitter.on("openPanel", () => {
           <span title="关闭配置">
             <IconifyIconOffline
               class="dark:text-white"
-              icon="close"
+              :icon="Close"
               @click="show = !show"
             />
           </span>

+ 4 - 2
src/layout/components/search/components/SearchFooter.vue

@@ -5,8 +5,8 @@
       确认
     </span>
     <span class="search-footer-item">
-      <IconifyIconOffline icon="arrow-up-line" class="icon" />
-      <IconifyIconOffline icon="arrow-down-line" class="icon" />
+      <IconifyIconOffline :icon="ArrowUpLine" class="icon" />
+      <IconifyIconOffline :icon="ArrowDownLine" class="icon" />
       切换
     </span>
     <span class="search-footer-item">
@@ -17,6 +17,8 @@
 </template>
 
 <script setup lang="ts">
+import ArrowUpLine from "@iconify-icons/ri/arrow-up-line";
+import ArrowDownLine from "@iconify-icons/ri/arrow-down-line";
 import mdiKeyboardEsc from "@/assets/svg/keyboard_esc.svg?component";
 import enterOutlined from "@/assets/svg/enter_outlined.svg?component";
 </script>

+ 2 - 1
src/layout/components/search/components/SearchModal.vue

@@ -9,6 +9,7 @@ import { transformI18n } from "@/plugins/i18n";
 import { useDebounceFn, onKeyStroke } from "@vueuse/core";
 import { ref, watch, computed, nextTick, shallowRef } from "vue";
 import { usePermissionStoreHook } from "@/store/modules/permission";
+import Search from "@iconify-icons/ep/search";
 
 interface Props {
   /** 弹窗显隐 */
@@ -148,7 +149,7 @@ onKeyStroke("ArrowDown", handleDown);
     >
       <template #prefix>
         <span class="el-input__icon">
-          <IconifyIconOffline icon="search" />
+          <IconifyIconOffline :icon="Search" />
         </span>
       </template>
     </el-input>

+ 2 - 1
src/layout/components/search/components/SearchResult.vue

@@ -4,6 +4,7 @@ import { useI18n } from "vue-i18n";
 import { useEpThemeStoreHook } from "@/store/modules/epTheme";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import enterOutlined from "@/assets/svg/enter_outlined.svg?component";
+import Bookmark2Line from "@iconify-icons/ri/bookmark-2-line";
 
 const { t } = useI18n();
 
@@ -67,7 +68,7 @@ function handleTo() {
         @click="handleTo"
         @mouseenter="handleMouse(item)"
       >
-        <component :is="useRenderIcon(item.meta?.icon ?? 'bookmark-2-line')" />
+        <component :is="useRenderIcon(item.meta?.icon ?? Bookmark2Line)" />
         <span class="result-item-title">{{ t(item.meta?.title) }}</span>
         <enterOutlined />
       </div>

+ 3 - 1
src/layout/components/search/index.vue

@@ -1,6 +1,8 @@
 <script setup lang="ts">
 import { SearchModal } from "./components";
 import { useBoolean } from "../../hooks/useBoolean";
+import Search from "@iconify-icons/ep/search";
+
 const { bool: show, toggle } = useBoolean();
 function handleSearch() {
   toggle();
@@ -12,7 +14,7 @@ function handleSearch() {
     class="search-container w-[40px] h-[48px] flex-c cursor-pointer navbar-bg-hover"
     @click="handleSearch"
   >
-    <IconifyIconOffline icon="search" />
+    <IconifyIconOffline :icon="Search" />
   </div>
   <SearchModal v-model:value="show" />
 </template>

+ 4 - 2
src/layout/components/setting/index.vue

@@ -30,6 +30,8 @@ import { toggleTheme } from "@pureadmin/theme/dist/browser-utils";
 
 import dayIcon from "@/assets/svg/day.svg?component";
 import darkIcon from "@/assets/svg/dark.svg?component";
+import Check from "@iconify-icons/ep/check";
+import Logout from "@iconify-icons/ri/logout-circle-r-line";
 
 const router = useRouter();
 const { device } = useNav();
@@ -299,7 +301,7 @@ nextTick(() => {
           :size="17"
           :color="getThemeColor(item.themeColor)"
         >
-          <IconifyIconOffline icon="check" />
+          <IconifyIconOffline :icon="Check" />
         </el-icon>
       </li>
     </ul>
@@ -380,7 +382,7 @@ nextTick(() => {
       @click="onReset"
     >
       <IconifyIconOffline
-        icon="fa-sign-out"
+        :icon="Logout"
         width="15"
         height="15"
         style="margin-right: 4px"

+ 7 - 4
src/layout/components/sidebar/horizontal.vue

@@ -7,6 +7,9 @@ import { useNav } from "@/layout/hooks/useNav";
 import { useTranslationLang } from "../../hooks/useTranslationLang";
 import { usePermissionStoreHook } from "@/store/modules/permission";
 import globalization from "@/assets/svg/globalization.svg?component";
+import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
+import Setting from "@iconify-icons/ri/settings-3-line";
+import Check from "@iconify-icons/ep/check";
 
 const menuRef = ref();
 
@@ -76,7 +79,7 @@ watch(
               @click="translationCh"
             >
               <span class="check-zh" v-show="locale === 'zh'">
-                <IconifyIconOffline icon="check" />
+                <IconifyIconOffline :icon="Check" />
               </span>
               简体中文
             </el-dropdown-item>
@@ -86,7 +89,7 @@ watch(
               @click="translationEn"
             >
               <span class="check-en" v-show="locale === 'en'">
-                <IconifyIconOffline icon="check" />
+                <IconifyIconOffline :icon="Check" />
               </span>
               English
             </el-dropdown-item>
@@ -106,7 +109,7 @@ watch(
           <el-dropdown-menu class="logout">
             <el-dropdown-item @click="logout">
               <IconifyIconOffline
-                icon="logout-circle-r-line"
+                :icon="LogoutCircleRLine"
                 style="margin: 5px"
               />
               {{ t("buttons.hsLoginOut") }}
@@ -119,7 +122,7 @@ watch(
         :title="t('buttons.hssystemSet')"
         @click="onPanel"
       >
-        <IconifyIconOffline icon="setting" />
+        <IconifyIconOffline :icon="Setting" />
       </span>
     </div>
   </div>

+ 3 - 1
src/layout/components/sidebar/leftCollapse.vue

@@ -1,5 +1,7 @@
 <script setup lang="ts">
 import { useDark } from "@pureadmin/utils";
+import MenuFold from "@iconify-icons/ri/menu-fold-fill";
+import MenuUnfold from "@iconify-icons/ri/menu-unfold-fill";
 
 interface Props {
   isActive: boolean;
@@ -27,7 +29,7 @@ const toggleClick = () => {
       :content="props.isActive ? '点击折叠' : '点击展开'"
     >
       <IconifyIconOffline
-        :icon="props.isActive ? 'menu-fold' : 'menu-unfold'"
+        :icon="props.isActive ? MenuFold : MenuUnfold"
         class="cursor-pointer inline-block align-middle text-primary hover:text-primary dark:hover:!text-white w-[16px] h-[16px] ml-4 mb-1"
         @click="toggleClick"
       />

+ 7 - 4
src/layout/components/sidebar/mixNav.vue

@@ -9,6 +9,9 @@ import { getParentPaths, findRouteByPath } from "@/router/utils";
 import { useTranslationLang } from "../../hooks/useTranslationLang";
 import { usePermissionStoreHook } from "@/store/modules/permission";
 import globalization from "@/assets/svg/globalization.svg?component";
+import LogoutCircleRLine from "@iconify-icons/ri/logout-circle-r-line";
+import Setting from "@iconify-icons/ri/settings-3-line";
+import Check from "@iconify-icons/ep/check";
 
 const menuRef = ref();
 const defaultActive = ref(null);
@@ -108,7 +111,7 @@ watch(
               @click="translationCh"
             >
               <span class="check-zh" v-show="locale === 'zh'">
-                <IconifyIconOffline icon="check" />
+                <IconifyIconOffline :icon="Check" />
               </span>
               简体中文
             </el-dropdown-item>
@@ -118,7 +121,7 @@ watch(
               @click="translationEn"
             >
               <span class="check-en" v-show="locale === 'en'">
-                <IconifyIconOffline icon="check" />
+                <IconifyIconOffline :icon="Check" />
               </span>
               English
             </el-dropdown-item>
@@ -138,7 +141,7 @@ watch(
           <el-dropdown-menu class="logout">
             <el-dropdown-item @click="logout">
               <IconifyIconOffline
-                icon="logout-circle-r-line"
+                :icon="LogoutCircleRLine"
                 style="margin: 5px"
               />
               {{ t("buttons.hsLoginOut") }}
@@ -151,7 +154,7 @@ watch(
         :title="t('buttons.hssystemSet')"
         @click="onPanel"
       >
-        <IconifyIconOffline icon="setting" />
+        <IconifyIconOffline :icon="Setting" />
       </span>
     </div>
   </div>

+ 13 - 5
src/layout/components/sidebar/sidebarItem.vue

@@ -7,6 +7,11 @@ import { transformI18n } from "@/plugins/i18n";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { ref, toRaw, PropType, nextTick, computed, CSSProperties } from "vue";
 
+import ArrowUp from "@iconify-icons/ep/arrow-up";
+import EpArrowDown from "@iconify-icons/ep/arrow-down";
+import ArrowLeft from "@iconify-icons/ep/arrow-left";
+import ArrowRight from "@iconify-icons/ep/arrow-right";
+
 const { layout, isCollapse } = useNav();
 
 const props = defineProps({
@@ -78,7 +83,13 @@ const getSpanStyle = computed(() => {
 });
 
 const expandCloseIcon = computed(() => {
-  return getConfig()?.MenuArrowIconNoTransition ? "expand-close-icon" : "";
+  if (!getConfig()?.MenuArrowIconNoTransition) return "";
+  return {
+    "expand-close-icon": useRenderIcon(EpArrowDown),
+    "expand-open-icon": useRenderIcon(ArrowUp),
+    "collapse-close-icon": useRenderIcon(ArrowRight),
+    "collapse-open-icon": useRenderIcon(ArrowLeft)
+  };
 });
 
 const onlyOneChild: childrenType = ref(null);
@@ -220,11 +231,8 @@ function resolvePath(routePath) {
   <el-sub-menu
     v-else
     ref="subMenu"
+    v-bind="expandCloseIcon"
     :index="resolvePath(props.item.path)"
-    v-bind:[expandCloseIcon]="useRenderIcon('ep-arrow-down')"
-    :expand-open-icon="useRenderIcon('ep-arrow-up')"
-    :collapse-close-icon="useRenderIcon('ep-arrow-right')"
-    :collapse-open-icon="useRenderIcon('ep-arrow-left')"
   >
     <template #title>
       <div v-if="toRaw(props.item.meta.icon)" class="sub-menu-icon">

+ 4 - 1
src/layout/components/sidebar/topCollapse.vue

@@ -1,4 +1,7 @@
 <script setup lang="ts">
+import MenuFold from "@iconify-icons/ri/menu-fold-fill";
+import MenuUnfold from "@iconify-icons/ri/menu-unfold-fill";
+
 interface Props {
   isActive: boolean;
 }
@@ -23,7 +26,7 @@ const toggleClick = () => {
     @click="toggleClick"
   >
     <IconifyIconOffline
-      :icon="props.isActive ? 'menu-fold' : 'menu-unfold'"
+      :icon="props.isActive ? MenuFold : MenuUnfold"
       class="inline-block align-middle hover:text-primary dark:hover:!text-white"
     />
   </div>

+ 15 - 11
src/layout/components/tag/index.vue

@@ -11,6 +11,13 @@ import { handleAliveRoute, delAliveRoutes } from "@/router/utils";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 import { useResizeObserver, useDebounceFn, useFullscreen } from "@vueuse/core";
 
+import ExitFullscreen from "@iconify-icons/ri/fullscreen-exit-fill";
+import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
+import ArrowDown from "@iconify-icons/ri/arrow-down-s-line";
+import ArrowRightSLine from "@iconify-icons/ri/arrow-right-s-line";
+import ArrowLeftSLine from "@iconify-icons/ri/arrow-left-s-line";
+import CloseBold from "@iconify-icons/ep/close-bold";
+
 const {
   route,
   router,
@@ -284,10 +291,10 @@ function onClickDrop(key, item, selectRoute?: RouteConfigs) {
       toggle();
       setTimeout(() => {
         if (isFullscreen.value) {
-          tagsViews[6].icon = "exit-fullscreen";
+          tagsViews[6].icon = ExitFullscreen;
           tagsViews[6].text = $t("buttons.hswholeExitFullScreen");
         } else {
-          tagsViews[6].icon = "fullscreen";
+          tagsViews[6].icon = Fullscreen;
           tagsViews[6].text = $t("buttons.hswholeFullScreen");
         }
       }, 100);
@@ -297,10 +304,10 @@ function onClickDrop(key, item, selectRoute?: RouteConfigs) {
       onContentFullScreen();
       setTimeout(() => {
         if (pureSetting.hiddenSideBar) {
-          tagsViews[7].icon = "exit-fullscreen";
+          tagsViews[7].icon = ExitFullscreen;
           tagsViews[7].text = $t("buttons.hscontentExitFullScreen");
         } else {
-          tagsViews[7].icon = "fullscreen";
+          tagsViews[7].icon = Fullscreen;
           tagsViews[7].text = $t("buttons.hscontentFullScreen");
         }
       }, 100);
@@ -496,7 +503,7 @@ onMounted(() => {
 <template>
   <div ref="containerDom" class="tags-view" v-if="!showTags">
     <span v-show="isShowArrow" class="arrow-left">
-      <IconifyIconOffline icon="arrow-left-s-line" @click="handleScroll(200)" />
+      <IconifyIconOffline :icon="ArrowLeftSLine" @click="handleScroll(200)" />
     </span>
     <div ref="scrollbarDom" class="scroll-container">
       <div class="tab select-none" ref="tabDom" :style="getTabStyle">
@@ -530,7 +537,7 @@ onMounted(() => {
             class="el-icon-close"
             @click.stop="deleteMenu(item)"
           >
-            <IconifyIconOffline icon="close-bold" />
+            <IconifyIconOffline :icon="CloseBold" />
           </span>
           <div
             :ref="'schedule' + index"
@@ -541,10 +548,7 @@ onMounted(() => {
       </div>
     </div>
     <span v-show="isShowArrow" class="arrow-right">
-      <IconifyIconOffline
-        icon="arrow-right-s-line"
-        @click="handleScroll(-200)"
-      />
+      <IconifyIconOffline :icon="ArrowRightSLine" @click="handleScroll(-200)" />
     </span>
     <!-- 右键菜单按钮 -->
     <transition name="el-zoom-in-top">
@@ -573,7 +577,7 @@ onMounted(() => {
       @command="handleCommand"
     >
       <span class="arrow-down">
-        <IconifyIconOffline icon="arrow-down" class="dark:text-white" />
+        <IconifyIconOffline :icon="ArrowDown" class="dark:text-white" />
       </span>
       <template #dropdown>
         <el-dropdown-menu>

+ 16 - 8
src/layout/hooks/useTag.ts

@@ -17,6 +17,14 @@ import { useSettingStoreHook } from "@/store/modules/settings";
 import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
 import { storageLocal, toggleClass, hasClass } from "@pureadmin/utils";
 
+import Fullscreen from "@iconify-icons/ri/fullscreen-fill";
+import CloseAllTags from "@iconify-icons/ri/subtract-line";
+import CloseOtherTags from "@iconify-icons/ri/text-spacing";
+import CloseRightTags from "@iconify-icons/ri/text-direction-l";
+import CloseLeftTags from "@iconify-icons/ri/text-direction-r";
+import RefreshRight from "@iconify-icons/ep/refresh-right";
+import Close from "@iconify-icons/ep/close";
+
 export function useTags() {
   const route = useRoute();
   const router = useRouter();
@@ -47,56 +55,56 @@ export function useTags() {
 
   const tagsViews = reactive<Array<tagsViewsType>>([
     {
-      icon: "refresh-right",
+      icon: RefreshRight,
       text: $t("buttons.hsreload"),
       divided: false,
       disabled: false,
       show: true
     },
     {
-      icon: "close",
+      icon: Close,
       text: $t("buttons.hscloseCurrentTab"),
       divided: false,
       disabled: multiTags.value.length > 1 ? false : true,
       show: true
     },
     {
-      icon: "close-left-tags",
+      icon: CloseLeftTags,
       text: $t("buttons.hscloseLeftTabs"),
       divided: true,
       disabled: multiTags.value.length > 1 ? false : true,
       show: true
     },
     {
-      icon: "close-right-tags",
+      icon: CloseRightTags,
       text: $t("buttons.hscloseRightTabs"),
       divided: false,
       disabled: multiTags.value.length > 1 ? false : true,
       show: true
     },
     {
-      icon: "close-other-tags",
+      icon: CloseOtherTags,
       text: $t("buttons.hscloseOtherTabs"),
       divided: true,
       disabled: multiTags.value.length > 2 ? false : true,
       show: true
     },
     {
-      icon: "close-all-tags",
+      icon: CloseAllTags,
       text: $t("buttons.hscloseAllTabs"),
       divided: false,
       disabled: multiTags.value.length > 1 ? false : true,
       show: true
     },
     {
-      icon: "fullscreen",
+      icon: Fullscreen,
       text: $t("buttons.hswholeFullScreen"),
       divided: true,
       disabled: false,
       show: true
     },
     {
-      icon: "fullscreen",
+      icon: Fullscreen,
       text: $t("buttons.hscontentFullScreen"),
       divided: false,
       disabled: false,

+ 6 - 3
src/layout/types.ts

@@ -1,17 +1,20 @@
+import type { IconifyIcon } from "@iconify/vue";
+import HomeFilled from "@iconify-icons/ep/home-filled";
+
 export const routerArrays: Array<RouteConfigs> = [
   {
     path: "/welcome",
     parentPath: "/",
     meta: {
       title: "menus.hshome",
-      icon: "home-filled"
+      icon: HomeFilled
     }
   }
 ];
 
 export type routeMetaType = {
   title?: string;
-  icon?: string;
+  icon?: string | IconifyIcon;
   showLink?: boolean;
   savedPosition?: boolean;
   auths?: Array<string>;
@@ -32,7 +35,7 @@ export type multiTagsType = {
 };
 
 export type tagsViewsType = {
-  icon: string;
+  icon: string | IconifyIcon;
   text: string;
   divided: boolean;
   disabled: boolean;

+ 2 - 1
src/router/modules/able.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { able } from "@/router/enums";
+import UbuntuFill from "@iconify-icons/ri/ubuntu-fill";
 
 export default {
   path: "/able",
   redirect: "/able/watermark",
   meta: {
-    icon: "ubuntu-fill",
+    icon: UbuntuFill,
     title: $t("menus.hsAble"),
     rank: able
   },

+ 0 - 1
src/router/modules/about.ts

@@ -5,7 +5,6 @@ export default {
   path: "/about",
   redirect: "/about/index",
   meta: {
-    // icon: "question-line",
     title: $t("menus.hsAbout"),
     rank: about
   },

+ 2 - 1
src/router/modules/components.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { components } from "@/router/enums";
+import Menu from "@iconify-icons/ep/menu";
 
 export default {
   path: "/components",
   redirect: "/components/video",
   meta: {
-    icon: "menu",
+    icon: Menu,
     title: $t("menus.hscomponents"),
     rank: components
   },

+ 2 - 1
src/router/modules/editor.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { editor } from "@/router/enums";
+import Edit from "@iconify-icons/ep/edit";
 
 export default {
   path: "/editor",
   redirect: "/editor/index",
   meta: {
-    icon: "edit",
+    icon: Edit,
     title: $t("menus.hseditor"),
     rank: editor
   },

+ 2 - 1
src/router/modules/error.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { error } from "@/router/enums";
+import InformationLine from "@iconify-icons/ri/information-line";
 
 export default {
   path: "/error",
   redirect: "/error/403",
   meta: {
-    icon: "information-line",
+    icon: InformationLine,
     title: $t("menus.hsabnormal"),
     rank: error
   },

+ 2 - 1
src/router/modules/flowchart.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { flowchart } from "@/router/enums";
+import SetUp from "@iconify-icons/ep/set-up";
 
 export default {
   path: "/flowChart",
   redirect: "/flowChart/index",
   meta: {
-    icon: "set-up",
+    icon: SetUp,
     title: $t("menus.hsflowChart"),
     rank: flowchart
   },

+ 3 - 1
src/router/modules/formdesign.ts

@@ -2,11 +2,13 @@ import { $t } from "@/plugins/i18n";
 import { formdesign } from "@/router/enums";
 const IFrame = () => import("@/layout/frameView.vue");
 
+import TerminalWindowLine from "@iconify-icons/ri/terminal-window-line";
+
 export default {
   path: "/formDesign",
   redirect: "/formDesign/index",
   meta: {
-    icon: "terminal-window-line",
+    icon: TerminalWindowLine,
     title: $t("menus.hsFormDesign"),
     rank: formdesign
   },

+ 2 - 1
src/router/modules/guide.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { guide } from "@/router/enums";
+import Guide from "@iconify-icons/ep/guide";
 
 export default {
   path: "/guide",
   redirect: "/guide/index",
   meta: {
-    icon: "guide",
+    icon: Guide,
     title: $t("menus.hsguide"),
     rank: guide
   },

+ 2 - 1
src/router/modules/home.ts

@@ -1,6 +1,7 @@
 import { $t } from "@/plugins/i18n";
 import { home } from "@/router/enums";
 const Layout = () => import("@/layout/index.vue");
+import HomeFilled from "@iconify-icons/ep/home-filled";
 
 export default {
   path: "/",
@@ -8,7 +9,7 @@ export default {
   component: Layout,
   redirect: "/welcome",
   meta: {
-    icon: "home-filled",
+    icon: HomeFilled,
     title: $t("menus.hshome"),
     rank: home
   },

+ 4 - 2
src/router/modules/list.ts

@@ -1,11 +1,13 @@
 import { $t } from "@/plugins/i18n";
 import { list } from "@/router/enums";
+import ListCheck from "@iconify-icons/ri/list-check";
+import Card from "@iconify-icons/ri/bank-card-line";
 
 export default {
   path: "/list",
   redirect: "/list/card",
   meta: {
-    icon: "list-check",
+    icon: ListCheck,
     title: $t("menus.hsList"),
     rank: list
   },
@@ -15,7 +17,7 @@ export default {
       name: "ListCard",
       component: () => import("@/views/list/card/index.vue"),
       meta: {
-        icon: "card",
+        icon: Card,
         title: $t("menus.hsListCard"),
         showParent: true
       }

+ 2 - 1
src/router/modules/nested.ts

@@ -1,12 +1,13 @@
 import { $t } from "@/plugins/i18n";
 import { nested } from "@/router/enums";
+import Histogram from "@iconify-icons/ep/histogram";
 
 export default {
   path: "/nested",
   redirect: "/nested/menu1/menu1-1",
   meta: {
     title: $t("menus.hsmenus"),
-    icon: "histogram",
+    icon: Histogram,
     rank: nested
   },
   children: [

+ 2 - 1
src/router/modules/ppt.ts

@@ -1,11 +1,12 @@
 import { ppt } from "@/router/enums";
 const IFrame = () => import("@/layout/frameView.vue");
+import Ppt from "@iconify-icons/ri/file-ppt-2-line";
 
 export default {
   path: "/ppt",
   redirect: "/ppt/index",
   meta: {
-    icon: "ppt",
+    icon: Ppt,
     title: "PPT",
     rank: ppt
   },

+ 2 - 1
src/router/modules/remaining.ts

@@ -1,5 +1,6 @@
 import { $t } from "@/plugins/i18n";
 const Layout = () => import("@/layout/index.vue");
+import HomeFilled from "@iconify-icons/ep/home-filled";
 
 export default [
   {
@@ -16,7 +17,7 @@ export default [
     path: "/redirect",
     component: Layout,
     meta: {
-      icon: "home-filled",
+      icon: HomeFilled,
       title: $t("menus.hshome"),
       showLink: false,
       rank: 102

+ 2 - 1
src/router/modules/result.ts

@@ -1,11 +1,12 @@
 import { $t } from "@/plugins/i18n";
 import { result } from "@/router/enums";
+import CheckboxCircleLine from "@iconify-icons/ri/checkbox-circle-line";
 
 export default {
   path: "/result",
   redirect: "/result/success",
   meta: {
-    icon: "checkbox-circle-line",
+    icon: CheckboxCircleLine,
     title: $t("menus.hsResult"),
     rank: result
   },

+ 0 - 8
src/style/reset.scss

@@ -111,7 +111,6 @@ button,
 [type="button"],
 [type="reset"],
 [type="submit"] {
-  -webkit-appearance: button;
   background-image: none;
 }
 
@@ -133,16 +132,10 @@ progress {
 }
 
 [type="search"] {
-  -webkit-appearance: textfield;
   outline-offset: -2px;
 }
 
-::-webkit-search-decoration {
-  -webkit-appearance: none;
-}
-
 ::-webkit-file-upload-button {
-  -webkit-appearance: button;
   font: inherit;
 }
 
@@ -211,7 +204,6 @@ iframe,
 embed,
 object {
   display: block;
-  vertical-align: middle;
 }
 
 img,

+ 2 - 1
src/views/able/menu-tree.vue

@@ -7,6 +7,7 @@ import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { extractPathList, deleteChildren } from "@/utils/tree";
 import { usePermissionStoreHook } from "@/store/modules/permission";
 import type { TreeNode } from "element-plus/es/components/tree-v2/src/types";
+import NodeTree from "@iconify-icons/ri/node-tree";
 
 defineOptions({
   name: "MenuTree"
@@ -50,7 +51,7 @@ const filterMethod = (query: string, node: treeNode) => {
           <el-link
             href="https://element-plus.gitee.io/zh-CN/component/tree-v2.html"
             target="_blank"
-            :icon="useRenderIcon('node-tree')"
+            :icon="useRenderIcon(NodeTree)"
             style="font-size: 16px; margin: 0 5px 4px 0"
           >
             Tree V2

+ 2 - 1
src/views/able/timeline.vue

@@ -2,6 +2,7 @@
 import { markRaw } from "vue";
 import { useRenderFlicker } from "@/components/ReFlicker";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Iphone from "@iconify-icons/ep/iphone";
 
 defineOptions({
   name: "TimeLine"
@@ -32,7 +33,7 @@ const activities = [
     content: "支持自定义图标",
     timestamp: lastBuildTime,
     color: "transparent",
-    icon: useRenderIcon("iphone", {
+    icon: useRenderIcon(Iphone, {
       color: "#0bbd87"
     })
   }

+ 2 - 1
src/views/components/draggable/index.vue

@@ -4,6 +4,7 @@ import Sortable, { Swap } from "sortablejs";
 import draggable from "vuedraggable/src/vuedraggable";
 import { useAppStoreHook } from "@/store/modules/app";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Rank from "@iconify-icons/ep/rank";
 
 defineOptions({
   name: "Draggable"
@@ -63,7 +64,7 @@ onMounted(() => {
           <el-link
             href="https://sortablejs.github.io/vue.draggable.next/#/simple"
             target="_blank"
-            :icon="useRenderIcon('rank')"
+            :icon="useRenderIcon(Rank)"
             style="font-size: 16px; margin: 0 4px 5px"
           >
             vuedraggable

+ 2 - 1
src/views/components/message/index.vue

@@ -3,6 +3,7 @@ import { h } from "vue";
 import hot from "@/assets/svg/hot.svg?component";
 import { message, closeAllMessage } from "@/utils/message";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Check from "@iconify-icons/ep/check";
 
 defineOptions({
   name: "Message"
@@ -68,7 +69,7 @@ defineOptions({
         @click="
           message('自定义消息图标', {
             customClass: 'el',
-            icon: useRenderIcon('check')
+            icon: useRenderIcon(Check)
           })
         "
       >

+ 2 - 1
src/views/components/video/index.vue

@@ -6,6 +6,7 @@ import { deviceDetection } from "@pureadmin/utils";
 import screenShot from "xgplayer/es/controls/screenShot";
 import playbackRate from "xgplayer/es/controls/playbackRate";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import VideoPlay from "@iconify-icons/ep/video-play";
 
 defineOptions({
   name: "Video"
@@ -38,7 +39,7 @@ onMounted(() => {
           <el-link
             href="https://v2.h5player.bytedance.com"
             target="_blank"
-            :icon="useRenderIcon('video-play')"
+            :icon="useRenderIcon(VideoPlay)"
             style="font-size: 16px; margin: 0 4px 5px"
           >
             西瓜播放器

+ 2 - 1
src/views/editor/index.vue

@@ -3,6 +3,7 @@ import "@wangeditor/editor/dist/css/style.css"; // 引入 css
 import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { onBeforeUnmount, ref, shallowRef, onMounted } from "vue";
+import Edit from "@iconify-icons/ep/edit";
 
 defineOptions({
   name: "Editor"
@@ -46,7 +47,7 @@ const handleCreated = editor => {
           <el-link
             href="https://www.wangeditor.com"
             target="_blank"
-            :icon="useRenderIcon('edit')"
+            :icon="useRenderIcon(Edit)"
             style="font-size: 16px; margin: 0 4px 5px"
           >
             Wangeditor

+ 3 - 1
src/views/flow-chart/index.vue

@@ -11,6 +11,8 @@ import { Snapshot, BpmnElement, Menu } from "@logicflow/extension";
 import { Control, NodePanel, DataDialog } from "@/components/ReFlowChart";
 import { toLogicflowData } from "@/components/ReFlowChart/src/adpterForTurbo";
 
+import SetUp from "@iconify-icons/ep/set-up";
+
 defineOptions({
   name: "FlowChart"
 });
@@ -71,7 +73,7 @@ onMounted(() => {
           <el-link
             href="http://logic-flow.org/"
             target="_blank"
-            :icon="useRenderIcon('set-up')"
+            :icon="useRenderIcon(SetUp)"
             style="font-size: 16px; margin: 0 4px 5px"
           >
             LogicFlow

+ 2 - 1
src/views/list/card/components/Card.vue

@@ -5,6 +5,7 @@ import laptopIcon from "@/assets/svg/laptop.svg?component";
 import serviceIcon from "@/assets/svg/service.svg?component";
 import calendarIcon from "@/assets/svg/calendar.svg?component";
 import userAvatarIcon from "@/assets/svg/user_avatar.svg?component";
+import More2Fill from "@iconify-icons/ri/more-2-fill";
 
 defineOptions({
   name: "ReCard"
@@ -64,7 +65,7 @@ const cardLogoClass = computed(() => [
             {{ product.isSetup ? "已启用" : "已停用" }}
           </el-tag>
           <el-dropdown trigger="click" :disabled="!product.isSetup">
-            <IconifyIconOffline icon="more-vertical" class="text-[24px]" />
+            <IconifyIconOffline :icon="More2Fill" class="text-[24px]" />
             <template #dropdown>
               <el-dropdown-menu :disabled="!product.isSetup">
                 <el-dropdown-item @click="handleClickManage(product)">

+ 7 - 2
src/views/list/card/index.vue

@@ -6,6 +6,8 @@ import { ElMessageBox } from "element-plus";
 import { ref, onMounted, nextTick } from "vue";
 import dialogForm from "./components/DialogForm.vue";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Search from "@iconify-icons/ep/search";
+import AddFill from "@iconify-icons/ri/add-circle-line";
 
 defineOptions({
   name: "ListCard"
@@ -93,7 +95,10 @@ const handleManageProduct = product => {
 <template>
   <div class="main">
     <div class="w-full flex justify-between mb-4">
-      <el-button :icon="useRenderIcon('add')" @click="formDialogVisible = true">
+      <el-button
+        :icon="useRenderIcon(AddFill)"
+        @click="formDialogVisible = true"
+      >
         新建产品
       </el-button>
       <el-input
@@ -106,7 +111,7 @@ const handleManageProduct = product => {
           <el-icon class="el-input__icon">
             <IconifyIconOffline
               v-show="searchValue.length === 0"
-              icon="search"
+              :icon="Search"
             />
           </el-icon>
         </template>

+ 2 - 1
src/views/login/components/phone.vue

@@ -9,6 +9,7 @@ import { $t, transformI18n } from "@/plugins/i18n";
 import { useVerifyCode } from "../utils/verifyCode";
 import { useUserStoreHook } from "@/store/modules/user";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Iphone from "@iconify-icons/ep/iphone";
 
 const { t } = useI18n();
 const loading = ref(false);
@@ -50,7 +51,7 @@ function onBack() {
           clearable
           v-model="ruleForm.phone"
           :placeholder="t('login.phone')"
-          :prefix-icon="useRenderIcon('iphone')"
+          :prefix-icon="useRenderIcon(Iphone)"
         />
       </el-form-item>
     </Motion>

+ 7 - 4
src/views/login/components/regist.vue

@@ -9,6 +9,9 @@ import { useVerifyCode } from "../utils/verifyCode";
 import { $t, transformI18n } from "@/plugins/i18n";
 import { useUserStoreHook } from "@/store/modules/user";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Lock from "@iconify-icons/ri/lock-fill";
+import Iphone from "@iconify-icons/ep/iphone";
+import User from "@iconify-icons/ri/user-3-fill";
 
 const { t } = useI18n();
 const checked = ref(false);
@@ -89,7 +92,7 @@ function onBack() {
           clearable
           v-model="ruleForm.username"
           :placeholder="t('login.username')"
-          :prefix-icon="useRenderIcon('user')"
+          :prefix-icon="useRenderIcon(User)"
         />
       </el-form-item>
     </Motion>
@@ -100,7 +103,7 @@ function onBack() {
           clearable
           v-model="ruleForm.phone"
           :placeholder="t('login.phone')"
-          :prefix-icon="useRenderIcon('iphone')"
+          :prefix-icon="useRenderIcon(Iphone)"
         />
       </el-form-item>
     </Motion>
@@ -136,7 +139,7 @@ function onBack() {
           show-password
           v-model="ruleForm.password"
           :placeholder="t('login.password')"
-          :prefix-icon="useRenderIcon('lock')"
+          :prefix-icon="useRenderIcon(Lock)"
         />
       </el-form-item>
     </Motion>
@@ -148,7 +151,7 @@ function onBack() {
           show-password
           v-model="ruleForm.repeatPassword"
           :placeholder="t('login.sure')"
-          :prefix-icon="useRenderIcon('lock')"
+          :prefix-icon="useRenderIcon(Lock)"
         />
       </el-form-item>
     </Motion>

+ 5 - 3
src/views/login/components/update.vue

@@ -9,6 +9,8 @@ import { useVerifyCode } from "../utils/verifyCode";
 import { $t, transformI18n } from "@/plugins/i18n";
 import { useUserStoreHook } from "@/store/modules/user";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Lock from "@iconify-icons/ri/lock-fill";
+import Iphone from "@iconify-icons/ep/iphone";
 
 const { t } = useI18n();
 const loading = ref(false);
@@ -73,7 +75,7 @@ function onBack() {
           clearable
           v-model="ruleForm.phone"
           :placeholder="t('login.phone')"
-          :prefix-icon="useRenderIcon('iphone')"
+          :prefix-icon="useRenderIcon(Iphone)"
         />
       </el-form-item>
     </Motion>
@@ -109,7 +111,7 @@ function onBack() {
           show-password
           v-model="ruleForm.password"
           :placeholder="t('login.password')"
-          :prefix-icon="useRenderIcon('lock')"
+          :prefix-icon="useRenderIcon(Lock)"
         />
       </el-form-item>
     </Motion>
@@ -121,7 +123,7 @@ function onBack() {
           show-password
           v-model="ruleForm.repeatPassword"
           :placeholder="t('login.sure')"
-          :prefix-icon="useRenderIcon('lock')"
+          :prefix-icon="useRenderIcon(Lock)"
         />
       </el-form-item>
     </Motion>

+ 6 - 4
src/views/login/index.vue

@@ -33,6 +33,9 @@ import { useDataThemeChange } from "@/layout/hooks/useDataThemeChange";
 import dayIcon from "@/assets/svg/day.svg?component";
 import darkIcon from "@/assets/svg/dark.svg?component";
 import globalization from "@/assets/svg/globalization.svg?component";
+import Lock from "@iconify-icons/ri/lock-fill";
+import Check from "@iconify-icons/ep/check";
+// import User from "@iconify-icons/ri/user-3-fill";
 
 defineOptions({
   name: "Login"
@@ -131,7 +134,7 @@ watch(imgCode, value => {
               <IconifyIconOffline
                 class="check-zh"
                 v-show="locale === 'zh'"
-                icon="check"
+                :icon="Check"
               />
               简体中文
             </el-dropdown-item>
@@ -141,7 +144,7 @@ watch(imgCode, value => {
               @click="translationEn"
             >
               <span class="check-en" v-show="locale === 'en'">
-                <IconifyIconOffline icon="check" />
+                <IconifyIconOffline :icon="Check" />
               </span>
               English
             </el-dropdown-item>
@@ -184,7 +187,6 @@ watch(imgCode, value => {
                   clearable
                   v-model="ruleForm.username"
                   :placeholder="t('login.username')"
-                  :prefix-icon="useRenderIcon('user')"
                 />
               </el-form-item>
             </Motion>
@@ -196,7 +198,7 @@ watch(imgCode, value => {
                   show-password
                   v-model="ruleForm.password"
                   :placeholder="t('login.password')"
-                  :prefix-icon="useRenderIcon('lock')"
+                  :prefix-icon="useRenderIcon(Lock)"
                 />
               </el-form-item>
             </Motion>

+ 4 - 2
src/views/pure-table/high/edit/columns.tsx

@@ -2,6 +2,8 @@ import { tableDataEdit } from "../data";
 import { message } from "@/utils/message";
 import { ref, computed, Transition } from "vue";
 import { clone, delay } from "@pureadmin/utils";
+import EditPen from "@iconify-icons/ep/edit-pen";
+import Check from "@iconify-icons/ep/check";
 
 // 温馨提示:编辑整行方法雷同,将cellRenderer后面渲染的组件抽出来做对应处理即可
 export function useColumns() {
@@ -60,13 +62,13 @@ export function useColumns() {
           </Transition>
           <iconify-icon-offline
             v-show={editing.value(index)}
-            icon="check"
+            icon={Check}
             class={iconClass.value(index)}
             onClick={() => onSure(index)}
           />
           <iconify-icon-offline
             v-show={activeIndex.value === index && !editing.value(index)}
-            icon="edits"
+            icon={EditPen}
             class={iconClass.value(index, true)}
             onClick={() => onEdit(row, index)}
           />

+ 6 - 4
src/views/result/columns.tsx

@@ -1,4 +1,6 @@
 import { IconifyIconOffline } from "@/components/ReIcon";
+import ArrowRightSLine from "@iconify-icons/ri/arrow-right-s-line";
+import CloseCircleLine from "@iconify-icons/ri/close-circle-line";
 
 export function useColumns() {
   const columns = [
@@ -7,7 +9,7 @@ export function useColumns() {
         return (
           <span class="flex items-center -mt-6">
             <IconifyIconOffline
-              icon="close-circle-line"
+              icon={CloseCircleLine}
               color="#F56C6C"
               width="18px"
               height="18px"
@@ -20,7 +22,7 @@ export function useColumns() {
             >
               立即解冻
               <IconifyIconOffline
-                icon="arrow-right-s-line"
+                icon={ArrowRightSLine}
                 color="var(--el-color-primary)"
                 width="18px"
                 height="18px"
@@ -35,7 +37,7 @@ export function useColumns() {
         return (
           <span class="flex items-center -mt-8">
             <IconifyIconOffline
-              icon="close-circle-line"
+              icon={CloseCircleLine}
               color="#F56C6C"
               width="18px"
               height="18px"
@@ -48,7 +50,7 @@ export function useColumns() {
             >
               立即升级
               <IconifyIconOffline
-                icon="arrow-right-s-line"
+                icon={ArrowRightSLine}
                 color="var(--el-color-primary)"
                 width="18px"
                 height="18px"

+ 10 - 5
src/views/system/dept/index.vue

@@ -6,6 +6,11 @@ import { FormInstance } from "element-plus";
 import { reactive, ref, onMounted } from "vue";
 import { TableProBar } from "@/components/ReTable";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Delete from "@iconify-icons/ep/delete";
+import EditPen from "@iconify-icons/ep/edit-pen";
+import Search from "@iconify-icons/ep/search";
+import Refresh from "@iconify-icons/ep/refresh";
+import AddFill from "@iconify-icons/ri/add-circle-line";
 
 defineOptions({
   name: "Dept"
@@ -74,13 +79,13 @@ onMounted(() => {
       <el-form-item>
         <el-button
           type="primary"
-          :icon="useRenderIcon('search')"
+          :icon="useRenderIcon(Search)"
           :loading="loading"
           @click="onSearch"
         >
           搜索
         </el-button>
-        <el-button :icon="useRenderIcon('refresh')" @click="resetForm(formRef)">
+        <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
           重置
         </el-button>
       </el-form-item>
@@ -94,7 +99,7 @@ onMounted(() => {
       @refresh="onSearch"
     >
       <template #buttons>
-        <el-button type="primary" :icon="useRenderIcon('add')">
+        <el-button type="primary" :icon="useRenderIcon(AddFill)">
           新增部门
         </el-button>
       </template>
@@ -124,7 +129,7 @@ onMounted(() => {
               type="primary"
               :size="size"
               @click="handleUpdate(row)"
-              :icon="useRenderIcon('edits')"
+              :icon="useRenderIcon(EditPen)"
             >
               修改
             </el-button>
@@ -135,7 +140,7 @@ onMounted(() => {
                   link
                   type="primary"
                   :size="size"
-                  :icon="useRenderIcon('delete')"
+                  :icon="useRenderIcon(Delete)"
                   @click="handleDelete(row)"
                 >
                   删除

+ 4 - 2
src/views/system/dict/config.vue

@@ -4,6 +4,8 @@ import { ref, reactive } from "vue";
 import { type Direction } from "element-plus";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { type VxeTableEvents, type VxeTableInstance } from "vxe-table";
+import Delete from "@iconify-icons/ep/delete";
+import EditPen from "@iconify-icons/ep/edit-pen";
 
 interface Props {
   drawer: boolean;
@@ -108,7 +110,7 @@ const checkboxChangeEvent: VxeTableEvents.CheckboxChange = ({ records }) => {
               <el-button
                 link
                 type="primary"
-                :icon="useRenderIcon('edits')"
+                :icon="useRenderIcon(EditPen)"
                 @click="editConfig(row)"
               >
                 编辑
@@ -116,7 +118,7 @@ const checkboxChangeEvent: VxeTableEvents.CheckboxChange = ({ records }) => {
               <el-button
                 link
                 type="primary"
-                :icon="useRenderIcon('delete')"
+                :icon="useRenderIcon(Delete)"
                 @click="delConfig(row)"
               >
                 删除

+ 4 - 2
src/views/system/dict/index.vue

@@ -14,6 +14,8 @@ import {
   type VxeTableEvents,
   type FormMethods
 } from "vxe-table";
+import Delete from "@iconify-icons/ep/delete";
+import EditPen from "@iconify-icons/ep/edit-pen";
 
 type onEditNRow = {
   name: string;
@@ -293,7 +295,7 @@ function onHide() {
           <el-button
             link
             type="primary"
-            :icon="useRenderIcon('edits')"
+            :icon="useRenderIcon(EditPen)"
             @click="onEdit(row)"
           >
             编辑
@@ -318,7 +320,7 @@ function onHide() {
           <el-button
             link
             type="primary"
-            :icon="useRenderIcon('delete')"
+            :icon="useRenderIcon(Delete)"
             @click="confirmEvent"
           >
             删除

+ 16 - 8
src/views/system/role/index.vue

@@ -6,6 +6,14 @@ import { type FormInstance } from "element-plus";
 import { TableProBar } from "@/components/ReTable";
 import { type PaginationProps } from "@pureadmin/table";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+import Database from "@iconify-icons/ri/database-2-line";
+import More from "@iconify-icons/ep/more-filled";
+import Delete from "@iconify-icons/ep/delete";
+import EditPen from "@iconify-icons/ep/edit-pen";
+import Search from "@iconify-icons/ep/search";
+import Refresh from "@iconify-icons/ep/refresh";
+import Menu from "@iconify-icons/ep/menu";
+import AddFill from "@iconify-icons/ri/add-circle-line";
 
 defineOptions({
   name: "Role"
@@ -94,13 +102,13 @@ onMounted(() => {
       <el-form-item>
         <el-button
           type="primary"
-          :icon="useRenderIcon('search')"
+          :icon="useRenderIcon(Search)"
           :loading="loading"
           @click="onSearch"
         >
           搜索
         </el-button>
-        <el-button :icon="useRenderIcon('refresh')" @click="resetForm(formRef)">
+        <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
           重置
         </el-button>
       </el-form-item>
@@ -113,7 +121,7 @@ onMounted(() => {
       @refresh="onSearch"
     >
       <template #buttons>
-        <el-button type="primary" :icon="useRenderIcon('add')">
+        <el-button type="primary" :icon="useRenderIcon(AddFill)">
           新增角色
         </el-button>
       </template>
@@ -144,7 +152,7 @@ onMounted(() => {
               type="primary"
               :size="size"
               @click="handleUpdate(row)"
-              :icon="useRenderIcon('edits')"
+              :icon="useRenderIcon(EditPen)"
             >
               修改
             </el-button>
@@ -155,7 +163,7 @@ onMounted(() => {
                   link
                   type="primary"
                   :size="size"
-                  :icon="useRenderIcon('delete')"
+                  :icon="useRenderIcon(Delete)"
                   @click="handleDelete(row)"
                 >
                   删除
@@ -169,7 +177,7 @@ onMounted(() => {
                 type="primary"
                 :size="size"
                 @click="handleUpdate(row)"
-                :icon="useRenderIcon('more')"
+                :icon="useRenderIcon(More)"
               />
               <template #dropdown>
                 <el-dropdown-menu>
@@ -179,7 +187,7 @@ onMounted(() => {
                       link
                       type="primary"
                       :size="size"
-                      :icon="useRenderIcon('menu')"
+                      :icon="useRenderIcon(Menu)"
                     >
                       菜单权限
                     </el-button>
@@ -190,7 +198,7 @@ onMounted(() => {
                       link
                       type="primary"
                       :size="size"
-                      :icon="useRenderIcon('database')"
+                      :icon="useRenderIcon(Database)"
                     >
                       数据权限
                     </el-button>

+ 17 - 11
src/views/system/user/index.vue

@@ -8,6 +8,15 @@ import { TableProBar } from "@/components/ReTable";
 import { type PaginationProps } from "@pureadmin/table";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 
+import Role from "@iconify-icons/ri/admin-line";
+import Password from "@iconify-icons/ri/lock-password-line";
+import More from "@iconify-icons/ep/more-filled";
+import Delete from "@iconify-icons/ep/delete";
+import EditPen from "@iconify-icons/ep/edit-pen";
+import Search from "@iconify-icons/ep/search";
+import Refresh from "@iconify-icons/ep/refresh";
+import AddFill from "@iconify-icons/ri/add-circle-line";
+
 defineOptions({
   name: "User"
 });
@@ -104,16 +113,13 @@ onMounted(() => {
         <el-form-item>
           <el-button
             type="primary"
-            :icon="useRenderIcon('search')"
+            :icon="useRenderIcon(Search)"
             :loading="loading"
             @click="onSearch"
           >
             搜索
           </el-button>
-          <el-button
-            :icon="useRenderIcon('refresh')"
-            @click="resetForm(formRef)"
-          >
+          <el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)">
             重置
           </el-button>
         </el-form-item>
@@ -126,7 +132,7 @@ onMounted(() => {
         @refresh="onSearch"
       >
         <template #buttons>
-          <el-button type="primary" :icon="useRenderIcon('add')">
+          <el-button type="primary" :icon="useRenderIcon(AddFill)">
             新增用户
           </el-button>
         </template>
@@ -156,7 +162,7 @@ onMounted(() => {
                 type="primary"
                 :size="size"
                 @click="handleUpdate(row)"
-                :icon="useRenderIcon('edits')"
+                :icon="useRenderIcon(EditPen)"
               >
                 修改
               </el-button>
@@ -167,7 +173,7 @@ onMounted(() => {
                     link
                     type="primary"
                     :size="size"
-                    :icon="useRenderIcon('delete')"
+                    :icon="useRenderIcon(Delete)"
                     @click="handleDelete(row)"
                   >
                     删除
@@ -181,7 +187,7 @@ onMounted(() => {
                   type="primary"
                   :size="size"
                   @click="handleUpdate(row)"
-                  :icon="useRenderIcon('more')"
+                  :icon="useRenderIcon(More)"
                 />
                 <template #dropdown>
                   <el-dropdown-menu>
@@ -191,7 +197,7 @@ onMounted(() => {
                         link
                         type="primary"
                         :size="size"
-                        :icon="useRenderIcon('password')"
+                        :icon="useRenderIcon(Password)"
                       >
                         重置密码
                       </el-button>
@@ -202,7 +208,7 @@ onMounted(() => {
                         link
                         type="primary"
                         :size="size"
-                        :icon="useRenderIcon('role')"
+                        :icon="useRenderIcon(Role)"
                       >
                         分配角色
                       </el-button>

+ 17 - 8
src/views/system/user/tree.vue

@@ -5,6 +5,15 @@ import { getDeptList } from "@/api/system";
 import { useRenderIcon } from "@/components/ReIcon/src/hooks";
 import { ref, watch, onMounted, getCurrentInstance } from "vue";
 
+import LocationCompany from "@iconify-icons/ep/add-location";
+import UnExpand from "@iconify-icons/mdi/arrow-expand-right";
+import Expand from "@iconify-icons/mdi/arrow-expand-down";
+import More2Fill from "@iconify-icons/ri/more-2-fill";
+import Reset from "@iconify-icons/ri/restart-line";
+import Dept from "@iconify-icons/ri/git-branch-line";
+import OfficeBuilding from "@iconify-icons/ep/office-building";
+import Search from "@iconify-icons/ep/search";
+
 interface Tree {
   id: number;
   name: string;
@@ -85,7 +94,7 @@ onMounted(async () => {
           <el-icon class="el-input__icon">
             <IconifyIconOffline
               v-show="searchValue.length === 0"
-              icon="search"
+              :icon="Search"
             />
           </el-icon>
         </template>
@@ -94,7 +103,7 @@ onMounted(async () => {
         <IconifyIconOffline
           class="w-[28px] cursor-pointer"
           width="18px"
-          icon="more-vertical"
+          :icon="More2Fill"
         />
         <template #dropdown>
           <el-dropdown-menu>
@@ -103,7 +112,7 @@ onMounted(async () => {
                 class="reset-margin !h-[20px] !text-gray-500 dark:!text-white dark:hover:!text-primary"
                 link
                 type="primary"
-                :icon="useRenderIcon('expand')"
+                :icon="useRenderIcon(Expand)"
                 @click="toggleRowExpansionAll(true)"
               >
                 展开全部
@@ -114,7 +123,7 @@ onMounted(async () => {
                 class="reset-margin !h-[20px] !text-gray-500 dark:!text-white dark:hover:!text-primary"
                 link
                 type="primary"
-                :icon="useRenderIcon('unExpand')"
+                :icon="useRenderIcon(UnExpand)"
                 @click="toggleRowExpansionAll(false)"
               >
                 折叠全部
@@ -125,7 +134,7 @@ onMounted(async () => {
                 class="reset-margin !h-[20px] !text-gray-500 dark:!text-white dark:hover:!text-primary"
                 link
                 type="primary"
-                :icon="useRenderIcon('reset')"
+                :icon="useRenderIcon(Reset)"
                 @click="onReset"
               >
                 重置状态
@@ -170,10 +179,10 @@ onMounted(async () => {
           <IconifyIconOffline
             :icon="
               data.type === 1
-                ? 'office-building'
+                ? OfficeBuilding
                 : data.type === 2
-                ? 'location-company'
-                : 'dept'
+                ? LocationCompany
+                : Dept
             "
           />
           {{ node.label }}

+ 12 - 6
src/views/welcome/components/columns.tsx

@@ -1,5 +1,11 @@
 import { IconifyIconOffline } from "@/components/ReIcon";
 import TypeIt from "@/components/ReTypeit";
+import OfficeBuilding from "@iconify-icons/ep/office-building";
+import Tickets from "@iconify-icons/ep/tickets";
+import Location from "@iconify-icons/ep/location";
+import Iphone from "@iconify-icons/ep/iphone";
+import Notebook from "@iconify-icons/ep/notebook";
+import User from "@iconify-icons/ri/user-3-fill";
 
 export function useColumns() {
   const lists = [
@@ -15,7 +21,7 @@ export function useColumns() {
       labelRenderer: () => (
         <div class="flex items-center">
           <el-icon>
-            <IconifyIconOffline icon="user" />
+            <IconifyIconOffline icon={User} />
           </el-icon>
           用户名
         </div>
@@ -26,7 +32,7 @@ export function useColumns() {
       labelRenderer: () => (
         <div class="flex items-center">
           <el-icon>
-            <IconifyIconOffline icon="iphone" />
+            <IconifyIconOffline icon={Iphone} />
           </el-icon>
           手机号
         </div>
@@ -37,7 +43,7 @@ export function useColumns() {
       labelRenderer: () => (
         <div class="flex items-center">
           <el-icon>
-            <IconifyIconOffline icon="location" />
+            <IconifyIconOffline icon={Location} />
           </el-icon>
           居住地
         </div>
@@ -51,7 +57,7 @@ export function useColumns() {
       labelRenderer: () => (
         <div class="flex items-center">
           <el-icon>
-            <IconifyIconOffline icon="tickets" />
+            <IconifyIconOffline icon={Tickets} />
           </el-icon>
           标签
         </div>
@@ -70,7 +76,7 @@ export function useColumns() {
       labelRenderer: () => (
         <div class="flex items-center">
           <el-icon>
-            <IconifyIconOffline icon="office-building" />
+            <IconifyIconOffline icon={OfficeBuilding} />
           </el-icon>
           联系地址
         </div>
@@ -84,7 +90,7 @@ export function useColumns() {
       labelRenderer: () => (
         <div class="flex items-center">
           <el-icon>
-            <IconifyIconOffline icon="notebook" />
+            <IconifyIconOffline icon={Notebook} />
           </el-icon>
           好好学习,天天向上
         </div>

+ 3 - 2
types/global.d.ts

@@ -5,6 +5,7 @@ import type {
   ComponentPublicInstance
 } from "vue";
 import type { ECharts } from "echarts";
+import type { IconifyIcon } from "@iconify/vue";
 import type { ResponsiveStorage } from "./index";
 import type { TableColumns } from "@pureadmin/table";
 import { type RouteComponent, type RouteLocationNormalized } from "vue-router";
@@ -189,7 +190,7 @@ declare global {
       /** 菜单名称(兼容国际化、非国际化,如何用国际化的写法就必须在根目录的`locales`文件夹下对应添加) `必填` */
       title: string;
       /** 菜单图标 `可选` */
-      icon?: string | FunctionalComponent;
+      icon?: string | FunctionalComponent | IconifyIcon;
       /** 菜单名称右侧的额外图标,支持`fontawesome`、`iconfont`、`element-plus-icon` `可选` */
       extraIcon?: {
         svg?: boolean;
@@ -247,7 +248,7 @@ declare global {
       /** 菜单名称(兼容国际化、非国际化,如何用国际化的写法就必须在根目录的`locales`文件夹下对应添加)`必填` */
       title: string;
       /** 菜单图标 `可选` */
-      icon?: string | FunctionalComponent;
+      icon?: string | FunctionalComponent | IconifyIcon;
       /** 是否在菜单中显示(默认`true`)`可选` */
       showLink?: boolean;
       /** 菜单升序排序,值越高排的越后(只针对顶级路由)`可选` */

+ 2 - 2
vite.config.ts

@@ -2,8 +2,8 @@ import dayjs from "dayjs";
 import { resolve } from "path";
 import pkg from "./package.json";
 import { warpperEnv } from "./build";
-import { include } from "./build/optimize";
 import { getPluginsList } from "./build/plugins";
+import { include, exclude } from "./build/optimize";
 import { UserConfigExport, ConfigEnv, loadEnv } from "vite";
 
 /** 当前执行node命令时文件夹的地址(工作目录) */
@@ -49,7 +49,7 @@ export default ({ command, mode }: ConfigEnv): UserConfigExport => {
     // https://cn.vitejs.dev/config/dep-optimization-options.html#dep-optimization-options
     optimizeDeps: {
       include,
-      exclude: ["@pureadmin/theme/dist/browser-utils"]
+      exclude
     },
     build: {
       sourcemap: false,

部分文件因为文件数量过多而无法显示