mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-27 22:55:59 +00:00
refactor: 优化前端代码结构和资源管理 style: 调整前端代码格式和样式 chore: 更新.gitignore和构建配置 fix: 修复前端资源路径和引用问题 docs: 更新前端文档和注释 perf: 优化前端性能和加载速度 test: 更新前端测试用例 build: 调整前端构建配置 ci: 更新CI/CD配置
76 lines
2.2 KiB
Vue
76 lines
2.2 KiB
Vue
<!-- 路由 / 侧栏菜单图标:与 IconSelect 存值规则一致 -->
|
||
<template>
|
||
<template v-if="!trimmedIcon" />
|
||
|
||
<ElIcon
|
||
v-else-if="elementComponent"
|
||
:class="iconClass"
|
||
:style="mergedStyle"
|
||
class="menu-route-icon"
|
||
>
|
||
<component :is="elementComponent" />
|
||
</ElIcon>
|
||
|
||
<ArtSvgIcon
|
||
v-else-if="isInvalidElementPrefix"
|
||
:icon="epFallback"
|
||
:color="color"
|
||
:class="iconClass"
|
||
:style="mergedStyle"
|
||
/>
|
||
|
||
<ArtSvgIcon
|
||
v-else
|
||
:icon="resolvedArtIcon"
|
||
:color="color"
|
||
:class="iconClass"
|
||
:style="mergedStyle"
|
||
/>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed } from "vue";
|
||
import ArtSvgIcon from "@/components/Core/base/art-svg-icon/index.vue";
|
||
import {
|
||
elementMenuIconToEpIconify,
|
||
isElementPlusStoredIcon,
|
||
resolveElementPlusIconComponent,
|
||
} from "@utils/menuIcon";
|
||
import { resolveIconForArtSvgIcon } from "@utils/menuIcon/remix";
|
||
|
||
defineOptions({ name: "MenuRouteIcon", inheritAttrs: false });
|
||
|
||
const props = defineProps<{
|
||
icon?: string;
|
||
color?: string;
|
||
/** 与 Vue `class` 一致(含条件 `false`) */
|
||
class?: string | string[] | Record<string, boolean> | null | undefined | false;
|
||
style?: Record<string, unknown> | string;
|
||
}>();
|
||
|
||
const trimmedIcon = computed(() => props.icon?.trim() ?? "");
|
||
|
||
const elementComponent = computed(() => resolveElementPlusIconComponent(trimmedIcon.value));
|
||
|
||
/** 仅带 `el-icon-` 却解析不出 EP 组件时走 ep 兜底,裸名无效则仍按自定义 SVG 处理 */
|
||
const isInvalidElementPrefix = computed(
|
||
() => !!trimmedIcon.value && isElementPlusStoredIcon(trimmedIcon.value) && !elementComponent.value
|
||
);
|
||
|
||
const epFallback = computed(() => elementMenuIconToEpIconify(trimmedIcon.value));
|
||
|
||
/** Iconify(含历史本地 SVG 文件名 → Remix `ri:`) */
|
||
const resolvedArtIcon = computed(() => resolveIconForArtSvgIcon(trimmedIcon.value));
|
||
|
||
const iconClass = computed(() =>
|
||
props.class === false || props.class == null ? undefined : props.class
|
||
);
|
||
const mergedStyle = computed(() => {
|
||
const base = typeof props.style === "object" && props.style !== null ? { ...props.style } : {};
|
||
if (props.color) {
|
||
(base as Record<string, string>).color = props.color;
|
||
}
|
||
return base as Record<string, string>;
|
||
});
|
||
</script>
|