Files
kra-new/web/src/components/logo/index.vue
T

93 lines
2.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<script setup>
import { computed, ref, watchEffect } from 'vue';
import { useThemeStore } from '@/pinia';
import { storeToRefs } from 'pinia';
const props = defineProps({
// logo 尺寸,单位为:rem
size: {
type: Number,
default: 2
},
// 侧栏深色时强制走暗色 logo:浅色主题 + 深色侧边栏场景下全局 isDark 仍为 false,
// 通栏侧边 / 移动抽屉把此值传进来,让 logo 连同侧栏一起变深。
dark: {
type: Boolean,
default: false
}
})
const darkLogoPath = '/business-logo.png'
const lightLogoPath = '/business-logo.png'
const themeStore = useThemeStore();
const { isDark } = storeToRefs(themeStore);
// 有效暗色:全局暗色 或 侧栏深色(props.dark)任一成立即走暗色 logo
const effectiveDark = computed(() => props.dark || isDark.value);
const logoSrc = ref('');
const showTextPlaceholder = ref(false);
// 检查图片是否存在
function checkImageExists(url) {
return new Promise((resolve) => {
const tryToLoad = new Image();
tryToLoad.onload = () => resolve(true);
tryToLoad.onerror = () => resolve(false);
tryToLoad.src = url;
});
}
watchEffect(async (onCleanup) => {
// effectiveDark 快速翻转时,用 stale 标记丢弃过期的异步结果,避免旧结果覆盖新值
let stale = false
onCleanup(() => (stale = true))
showTextPlaceholder.value = false; // 重置占位符状态
// 暗色模式直接 load,可以省一次亮色的 load
if (effectiveDark.value && await checkImageExists(darkLogoPath)) {
if (!stale) logoSrc.value = darkLogoPath;
return;
}
if (await checkImageExists(lightLogoPath)) {
if (!stale) logoSrc.value = lightLogoPath;
return
}
if (stale) return
// 到这里就包没有提供两种 logo 了
showTextPlaceholder.value = true;
console.error(
'错误: 在公共目录中找不到 business-logo.png。'
);
console.warn(
'解决方案: 请在 public 目录中放置 business-logo.png。'
);
});
// 直接用 16px 作为默认的基准大小
const SPACING = 16
function getSize() {
return {
width: `${props.size * SPACING}px`,
height: `${props.size * SPACING}px`,
}
}
</script>
<template>
<img v-if="!showTextPlaceholder && logoSrc" :src="logoSrc" :alt="$KRA.appName" class="object-contain"
:style="{
...getSize()
}" />
<div v-else-if="showTextPlaceholder"
class="rounded-full bg-gray-300 dark:bg-gray-600 flex items-center justify-center text-gray-700 dark:text-gray-200 font-bold text-xs"
:style="{
...getSize()
}">
商务
</div>
</template>