Browse Source

feat(icon): findIcon function (#107)

* feat(icon): findIcon function

支持ElementPlus icon组件和 FontAwesomeIcon

* fix(menu): 支持第三方icon组件
hb0730 3 years ago
parent
commit
2d6ad99f6f

+ 37 - 1
src/components/ReIcon/index.ts

@@ -1,5 +1,7 @@
-import { App } from "vue";
+import { App, defineComponent } from "vue";
 import icon from "./src/Icon.vue";
+import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
+import { iconComponents } from "/@/plugins/element-plus";
 
 export const Icon = Object.assign(icon, {
   install(app: App) {
@@ -10,3 +12,37 @@ export const Icon = Object.assign(icon, {
 export default {
   Icon
 };
+/**
+ * find icon component
+ * @param icon icon图标
+ * @returns component
+ */
+export function findIconReg(icon: string) {
+  const faReg = /^fa-/;
+  if (faReg.test(icon)) {
+    return findIcon(icon.split(faReg)[1]);
+  } else {
+    return findIcon(icon, false);
+  }
+}
+export function findIcon(icon: String, isFa: Boolean = true) {
+  if (isFa) {
+    return defineComponent({
+      name: "FaIcon",
+      data() {
+        return { icon: icon };
+      },
+      components: { FontAwesomeIcon },
+      template: `<font-awesome-icon :icon="icon" />`
+    });
+  } else {
+    const components = iconComponents.filter(
+      component => component.name === icon
+    );
+    if (components.length > 0) {
+      return components[0];
+    } else {
+      return null;
+    }
+  }
+}

+ 8 - 3
src/layout/components/sidebar/sidebarItem.vue

@@ -4,7 +4,7 @@ import { PropType, ref, nextTick, getCurrentInstance } from "vue";
 import { childrenType } from "../../types";
 import { useAppStoreHook } from "/@/store/modules/app";
 import Icon from "/@/components/ReIcon/src/Icon.vue";
-
+import { findIconReg } from "/@/components/ReIcon";
 const instance = getCurrentInstance().appContext.app.config.globalProperties;
 const menuMode = instance.$storage.layout?.layout === "vertical";
 const pureApp = useAppStoreHook();
@@ -92,7 +92,10 @@ function resolvePath(routePath) {
       <el-icon v-show="props.item.meta.icon">
         <component
           :is="
-            onlyOneChild.meta.icon || (props.item.meta && props.item.meta.icon)
+            findIconReg(
+              onlyOneChild.meta.icon ||
+                (props.item.meta && props.item.meta.icon)
+            )
           "
         ></component>
       </el-icon>
@@ -144,7 +147,9 @@ function resolvePath(routePath) {
   >
     <template #title>
       <el-icon v-show="props.item.meta.icon" :class="props.item.meta.icon">
-        <component :is="props.item.meta && props.item.meta.icon"></component>
+        <component
+          :is="findIconReg(props.item.meta && props.item.meta.icon)"
+        ></component>
       </el-icon>
       <span v-if="!menuMode">{{ $t(props.item.meta.title) }}</span>
       <el-tooltip

+ 5 - 3
src/plugins/element-plus/index.ts

@@ -93,9 +93,10 @@ const components = [
   ElDescriptions,
   ElDescriptionsItem,
   ElBacktop,
-  ElSwitch,
-
-  // icon
+  ElSwitch
+];
+// icon
+export const iconComponents = [
   Check,
   Menu,
   HomeFilled,
@@ -115,6 +116,7 @@ const components = [
 const plugins = [ElLoading];
 
 export function useElementPlus(app: App) {
+  components.push(...iconComponents);
   components.forEach((component: Component) => {
     app.component(component.name, component);
   });