🐛 修复潜在的ssg问题

This commit is contained in:
li-chx 2025-10-05 03:01:52 +08:00
parent 51a39d498b
commit 1cefa4c661
7 changed files with 56 additions and 44 deletions

View File

@ -13,13 +13,24 @@ const eraseHeaderMarkdown = computed(() => props.markdown.replace(/^---[\s\S]*?-
const { colorMode } = storeToRefs(useColorModeStore());
const mounted = ref(false);
onMounted(() => {
mounted.value = true;
});
</script>
<template>
<div class="pt-0 bg-old-neutral-200 dark:bg-old-neutral-800 transition-colors duration-500">
<client-only>
<MdPreview :editor-id="editorId" :theme="colorMode" :model-value="eraseHeaderMarkdown" class="transition-all duration-500 max-w-full"/>
</client-only>
<MdPreview
v-if="mounted"
:key="editorId + '-' + colorMode"
:editor-id="editorId"
:theme="colorMode"
:model-value="eraseHeaderMarkdown"
class="transition-all duration-500 max-w-full"
/>
</div>
</template>

View File

@ -64,6 +64,7 @@ const renderChart = () => {
chart: {
type: 'bar',
backgroundColor: 'transparent',
reflow: false,
},
credits: {
enabled: false,
@ -127,7 +128,8 @@ const renderChart = () => {
dataLabels: {
enabled: true,
style: {
color: '#fff',
color: colorMode.value === 'light' ? '#4e4d55' : '#fff',
textOutline: 'none',
},
formatter: function () {
return toPercent(this.y); //
@ -178,11 +180,15 @@ const scrollbarOptions = {
},
};
const mounted = ref(false);
onMounted(() => {
mounted.value = true;
});
</script>
<template>
<div class="h-full">
<div v-if="noDataAvailable" class="flex items-center justify-center h-full p-8">
<div v-if="!mounted||noDataAvailable" class="flex items-center justify-center h-full p-8">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 112.01">
<g id="_图层_1" data-name="图层 1">
<polyline
@ -216,9 +222,7 @@ const scrollbarOptions = {
</svg>
</div>
<overlay-scrollbars-component v-else class="max-h-full" :options="scrollbarOptions">
<client-only>
<div ref="chartRef" class="w-full"/>
</client-only>
</overlay-scrollbars-component>
</div>
</template>

View File

@ -61,6 +61,11 @@ useRouter().beforeEach(() => {
useRouter().afterEach(() => {
isLoading.value = false;
});
const mounted = ref(false);
onMounted(() => {
mounted.value = true;
});
</script>
<template>
@ -75,7 +80,7 @@ useRouter().afterEach(() => {
}"
@mouseleave="collapsed = true">
<!-- header -->
<client-only>
<div v-if="mounted">
<Transition
enter-active-class="transition-opacity duration-500 ease-in-out"
enter-from-class="opacity-0"
@ -113,7 +118,7 @@ useRouter().afterEach(() => {
class="opacity-20 max-h-[48px] flex w-full h-full fixed bg-[url('/anime-8788959.jpg')] bg-cover bg-center"/>
</div>
</Transition>
</client-only>
</div>
<!-- navbar -->
<div
class="fixed z-10 w-full transition-all duration-500 dark:bg-gray-800/60 bg-old-neutral-50/40 backdrop-blur-sm dark:backdrop-blur-md">
@ -123,13 +128,8 @@ useRouter().afterEach(() => {
</div>
<div
class="transition-all duration-500 flex 2xl:w-[1240px] xl:w-[1020px] lg:w-[964px] md:w-[708px] sm:w-[580px] w-10/12">
<client-only>
<UNavigationMenu :items="items" :class="colorMode" class="w-full"/>
<template #fallback>
<!-- 骨架屏/占位内容 -->
<div class="w-full h-12 animate-pulse"></div>
</template>
</client-only>
<UNavigationMenu v-if="mounted" :items="items" :class="colorMode" class="w-full"/>
<div v-else class="w-full h-12 animate-pulse"></div>
</div>
<div class="flex-1 overflow-hidden">
<slot name="navbarRight" :is-scroll-down="isScrollDown"/>

View File

@ -33,9 +33,11 @@
"vue-router": "^4.5.1",
"word-count": "^0.3.1"
},
"packageManager": "pnpm@10.17.1",
"packageManager": "pnpm@10.18.0",
"devDependencies": {
"@iconify-json/clarity": "^1.2.4",
"@iconify-json/lucide": "^1.2.68",
"@iconify-json/material-symbols": "^1.2.40",
"@stylistic/eslint-plugin": "^5.4.0",
"@stylistic/eslint-plugin-jsx": "^4.4.1",
"@vue/eslint-config-typescript": "^14.6.0",

View File

@ -2,7 +2,6 @@
import { DataAnomaly, defaultMetaData } from '~/types/PostMetaData';
import type { PostMetaData } from '~/types/PostMetaData';
import breakpointsHelper from '~/utils/BreakpointsHelper';
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
withDefaults(defineProps<{
@ -45,6 +44,11 @@ function getCostTime(length: number | DataAnomaly | undefined) {
return `${minutes}分钟`;
}
}
const mounted = ref(false);
onMounted(() => {
mounted.value = true;
});
</script>
<template>
@ -94,24 +98,17 @@ function getCostTime(length: number | DataAnomaly | undefined) {
<overlay-scrollbars-component>
{{ metaData?.description }}
</overlay-scrollbars-component>
<Transition
enter-active-class="transition-opacity duration-500 ease-in-out"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition-opacity duration-500 ease-in-out"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div v-if="mounted" class="">
<TechStackCard
v-if="breakpointsHelper.greater('lg').value"
:async-key="'stack:' + metaData?.id"
:tech-stack="metaData?.tech_stack"
:tech-stack-icon-names="metaData?.tech_stack_icon_names"
:tech-stack-theme-colors="metaData?.tech_stack_theme_colors"
:tech-stack-percent="metaData?.tech_stack_percent"
class="min-w-64"
class="lg:w-64 w-0 transition-all duration-500"
/>
</Transition>
</div>
<div v-else class="min-w-64"/>
</div>
<hr/>
<div class="flex mt-2">

View File

@ -1,8 +1,6 @@
// darkVerify.js
if (
localStorage.getItem('system-theme-mode') === "dark" ||
(!localStorage.getItem('system-theme-mode') &&
window.matchMedia("(prefers-color-scheme: dark)").matches)
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
document.querySelector('html').classList.add('dark');
document.querySelector('html').classList.remove('light');

View File

@ -5,12 +5,12 @@ function getInitialMode(): 'light' | 'dark' {
if (document.documentElement.classList.contains('light')) return 'light';
// 其次用 localStorage
const val = localStorage.getItem('system-theme-mode');
if (!!val || (val !== 'light' && val !== 'dark'))
return 'light';
return val;
if (val === 'dark') return 'dark';
if (val === 'light') return 'light';
return 'light'; // 默认
}
return 'light'; // SSR 默认
};
}
const useColorModeStore = defineStore('colorMode', {
state: () => ({