NewLife/cube-front

feat(LogoBrand): 优化 Logo 组件,移除不必要的属性,调整标题显示逻辑
何炳宏 authored at 2026-05-23 10:32:55
a02d225
Tree
1 Parent(s) 4e31384
Summary: 1 changed files with 53 additions and 38 deletions.
Modified +53 -38
Modified +53 -38
diff --git a/core/components/LogoBrand.vue b/core/components/LogoBrand.vue
index b7122b0..ae92b9b 100644
--- a/core/components/LogoBrand.vue
+++ b/core/components/LogoBrand.vue
@@ -3,49 +3,47 @@
  * LogoBrand - Logo 和品牌名称组件
  * 用于导航栏左侧的品牌展示
  */
-import { computed } from 'vue';
+import { ref, computed } from 'vue';
 import { getConfig } from 'cube-front/core/configure';
 
 interface Props {
-  /** 自定义标题,为空时从配置读取 */
-  title?: string;
-  /** Logo 图标大小 */
-  iconSize?: number;
-  /** 是否显示标题文字 */
-  showTitle?: boolean;
+  /** 是否折叠(折叠时隐藏标题) */
+  collapsed?: boolean;
 }
 
 const props = withDefaults(defineProps<Props>(), {
-  title: '',
-  iconSize: 20,
-  showTitle: true,
+  collapsed: false,
 });
 
 const config = getConfig();
-const brandTitle = computed(() => props.title || config.base.title || 'Cube Front');
+const brandTitle = config.base.title || 'Cube Front';
+const brandLogo = computed(() => config.base.logo);
+
+// 图片 logo 相关
+const logoImgRef = ref<HTMLImageElement | null>(null);
+const logoAspectRatio = ref<number | null>(null);
+const onLogoLoad = (e: Event) => {
+  const img = e.target as HTMLImageElement;
+  if (img.naturalWidth && img.naturalHeight) {
+    logoAspectRatio.value = img.naturalWidth / img.naturalHeight;
+  }
+};
+// 根据图片宽高比和折叠状态决定是否显示标题
+const showLogoTitle = computed(() => {
+  if (props.collapsed) return false; // 折叠时隐藏
+  if (logoAspectRatio.value === null) return true; // 加载中默认显示
+  const ratio = logoAspectRatio.value;
+  return ratio > 0.9 && ratio < 1.1; // 正方形隐藏标题
+});
 </script>
 
 <template>
   <div class="logo-brand">
-    <div class="logo-icon">
-      <svg
-        :width="iconSize"
-        :height="iconSize"
-        viewBox="0 0 24 24"
-        fill="none"
-        stroke="currentColor"
-        stroke-width="2.2"
-        stroke-linecap="round"
-        stroke-linejoin="round"
-      >
-        <path
-          d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"
-        />
-        <polyline points="3.27 6.96 12 12.01 20.73 6.96" />
-        <line x1="12" y1="22.08" x2="12" y2="12" />
-      </svg>
+    <!-- 图片 logo -->
+    <div v-if="brandLogo" class="logo-img-wrap">
+      <img ref="logoImgRef" :src="brandLogo" :alt="brandTitle" @load="onLogoLoad" />
     </div>
-    <span v-if="showTitle" class="logo-title">{{ brandTitle }}</span>
+    <span v-if="showLogoTitle" class="logo-title">{{ brandTitle }}</span>
   </div>
 </template>
 
@@ -54,26 +52,43 @@ const brandTitle = computed(() => props.title || config.base.title || 'Cube Fron
   display: flex;
   align-items: center;
   gap: 10px;
+  width: 100%;
+  box-sizing: border-box;
+
+  .collapsed & {
+    padding: 8px 0;
+    justify-content: center;
+  }
 }
 
-.logo-icon {
+.logo-img-wrap {
   display: flex;
   align-items: center;
   justify-content: center;
-  width: 34px;
-  height: 34px;
-  border-radius: 10px;
-  background: linear-gradient(135deg, #1e40af 0%, #2563eb 100%);
-  color: #ffffff;
   flex-shrink: 0;
-  box-shadow: 0 2px 8px rgba(30, 64, 175, 0.2);
+  height: 100%;
+  width: auto;
+  max-width: 100%;
+  border-radius: 6px;
+  overflow: hidden;
+
+  img {
+    height: 100%;
+    width: auto;
+    max-width: 100%;
+    object-fit: contain;
+  }
 }
 
 .logo-title {
+  flex: 1;
   font-weight: 700;
-  font-size: 18px;
-  color: #1e293b;
+  font-size: 14px;
+  color: var(--text-primary);
   letter-spacing: -0.02em;
   white-space: nowrap;
+  overflow: hidden;
+  text-overflow: ellipsis;
+  min-width: 0;
 }
 </style>
\ No newline at end of file