🐛 修复潜在的ssg问题
This commit is contained in:
parent
51a39d498b
commit
1cefa4c661
|
|
@ -13,13 +13,24 @@ const eraseHeaderMarkdown = computed(() => props.markdown.replace(/^---[\s\S]*?-
|
||||||
|
|
||||||
const { colorMode } = storeToRefs(useColorModeStore());
|
const { colorMode } = storeToRefs(useColorModeStore());
|
||||||
|
|
||||||
|
const mounted = ref(false);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
mounted.value = true;
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="pt-0 bg-old-neutral-200 dark:bg-old-neutral-800 transition-colors duration-500">
|
<div class="pt-0 bg-old-neutral-200 dark:bg-old-neutral-800 transition-colors duration-500">
|
||||||
<client-only>
|
<MdPreview
|
||||||
<MdPreview :editor-id="editorId" :theme="colorMode" :model-value="eraseHeaderMarkdown" class="transition-all duration-500 max-w-full"/>
|
v-if="mounted"
|
||||||
</client-only>
|
:key="editorId + '-' + colorMode"
|
||||||
|
:editor-id="editorId"
|
||||||
|
:theme="colorMode"
|
||||||
|
:model-value="eraseHeaderMarkdown"
|
||||||
|
class="transition-all duration-500 max-w-full"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ const renderChart = () => {
|
||||||
chart: {
|
chart: {
|
||||||
type: 'bar',
|
type: 'bar',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
|
reflow: false,
|
||||||
},
|
},
|
||||||
credits: {
|
credits: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
@ -127,7 +128,8 @@ const renderChart = () => {
|
||||||
dataLabels: {
|
dataLabels: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
style: {
|
style: {
|
||||||
color: '#fff',
|
color: colorMode.value === 'light' ? '#4e4d55' : '#fff',
|
||||||
|
textOutline: 'none',
|
||||||
},
|
},
|
||||||
formatter: function () {
|
formatter: function () {
|
||||||
return toPercent(this.y); // 自定义条形图值的显示格式
|
return toPercent(this.y); // 自定义条形图值的显示格式
|
||||||
|
|
@ -178,11 +180,15 @@ const scrollbarOptions = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const mounted = ref(false);
|
||||||
|
onMounted(() => {
|
||||||
|
mounted.value = true;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="h-full">
|
<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">
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 112.01">
|
||||||
<g id="_图层_1" data-name="图层 1">
|
<g id="_图层_1" data-name="图层 1">
|
||||||
<polyline
|
<polyline
|
||||||
|
|
@ -216,9 +222,7 @@ const scrollbarOptions = {
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<overlay-scrollbars-component v-else class="max-h-full" :options="scrollbarOptions">
|
<overlay-scrollbars-component v-else class="max-h-full" :options="scrollbarOptions">
|
||||||
<client-only>
|
<div ref="chartRef" class="w-full"/>
|
||||||
<div ref="chartRef" class="w-full"/>
|
|
||||||
</client-only>
|
|
||||||
</overlay-scrollbars-component>
|
</overlay-scrollbars-component>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,11 @@ useRouter().beforeEach(() => {
|
||||||
useRouter().afterEach(() => {
|
useRouter().afterEach(() => {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const mounted = ref(false);
|
||||||
|
onMounted(() => {
|
||||||
|
mounted.value = true;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -75,7 +80,7 @@ useRouter().afterEach(() => {
|
||||||
}"
|
}"
|
||||||
@mouseleave="collapsed = true">
|
@mouseleave="collapsed = true">
|
||||||
<!-- header -->
|
<!-- header -->
|
||||||
<client-only>
|
<div v-if="mounted">
|
||||||
<Transition
|
<Transition
|
||||||
enter-active-class="transition-opacity duration-500 ease-in-out"
|
enter-active-class="transition-opacity duration-500 ease-in-out"
|
||||||
enter-from-class="opacity-0"
|
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"/>
|
class="opacity-20 max-h-[48px] flex w-full h-full fixed bg-[url('/anime-8788959.jpg')] bg-cover bg-center"/>
|
||||||
</div>
|
</div>
|
||||||
</Transition>
|
</Transition>
|
||||||
</client-only>
|
</div>
|
||||||
<!-- navbar -->
|
<!-- navbar -->
|
||||||
<div
|
<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">
|
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>
|
||||||
<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">
|
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 v-if="mounted" :items="items" :class="colorMode" class="w-full"/>
|
||||||
<UNavigationMenu :items="items" :class="colorMode" class="w-full"/>
|
<div v-else class="w-full h-12 animate-pulse"></div>
|
||||||
<template #fallback>
|
|
||||||
<!-- 骨架屏/占位内容 -->
|
|
||||||
<div class="w-full h-12 animate-pulse"></div>
|
|
||||||
</template>
|
|
||||||
</client-only>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 overflow-hidden">
|
<div class="flex-1 overflow-hidden">
|
||||||
<slot name="navbarRight" :is-scroll-down="isScrollDown"/>
|
<slot name="navbarRight" :is-scroll-down="isScrollDown"/>
|
||||||
|
|
|
||||||
|
|
@ -33,9 +33,11 @@
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"word-count": "^0.3.1"
|
"word-count": "^0.3.1"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.17.1",
|
"packageManager": "pnpm@10.18.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@iconify-json/clarity": "^1.2.4",
|
||||||
"@iconify-json/lucide": "^1.2.68",
|
"@iconify-json/lucide": "^1.2.68",
|
||||||
|
"@iconify-json/material-symbols": "^1.2.40",
|
||||||
"@stylistic/eslint-plugin": "^5.4.0",
|
"@stylistic/eslint-plugin": "^5.4.0",
|
||||||
"@stylistic/eslint-plugin-jsx": "^4.4.1",
|
"@stylistic/eslint-plugin-jsx": "^4.4.1",
|
||||||
"@vue/eslint-config-typescript": "^14.6.0",
|
"@vue/eslint-config-typescript": "^14.6.0",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import { DataAnomaly, defaultMetaData } from '~/types/PostMetaData';
|
import { DataAnomaly, defaultMetaData } from '~/types/PostMetaData';
|
||||||
import type { PostMetaData } from '~/types/PostMetaData';
|
import type { PostMetaData } from '~/types/PostMetaData';
|
||||||
import breakpointsHelper from '~/utils/BreakpointsHelper';
|
|
||||||
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
import { OverlayScrollbarsComponent } from 'overlayscrollbars-vue';
|
||||||
|
|
||||||
withDefaults(defineProps<{
|
withDefaults(defineProps<{
|
||||||
|
|
@ -45,6 +44,11 @@ function getCostTime(length: number | DataAnomaly | undefined) {
|
||||||
return `${minutes}分钟`;
|
return `${minutes}分钟`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mounted = ref(false);
|
||||||
|
onMounted(() => {
|
||||||
|
mounted.value = true;
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
@ -94,24 +98,17 @@ function getCostTime(length: number | DataAnomaly | undefined) {
|
||||||
<overlay-scrollbars-component>
|
<overlay-scrollbars-component>
|
||||||
{{ metaData?.description }}
|
{{ metaData?.description }}
|
||||||
</overlay-scrollbars-component>
|
</overlay-scrollbars-component>
|
||||||
<Transition
|
<div v-if="mounted" class="">
|
||||||
enter-active-class="transition-opacity duration-500 ease-in-out"
|
<TechStackCard
|
||||||
enter-from-class="opacity-0"
|
:async-key="'stack:' + metaData?.id"
|
||||||
enter-to-class="opacity-100"
|
:tech-stack="metaData?.tech_stack"
|
||||||
leave-active-class="transition-opacity duration-500 ease-in-out"
|
:tech-stack-icon-names="metaData?.tech_stack_icon_names"
|
||||||
leave-from-class="opacity-100"
|
:tech-stack-theme-colors="metaData?.tech_stack_theme_colors"
|
||||||
leave-to-class="opacity-0"
|
:tech-stack-percent="metaData?.tech_stack_percent"
|
||||||
>
|
class="lg:w-64 w-0 transition-all duration-500"
|
||||||
<TechStackCard
|
/>
|
||||||
v-if="breakpointsHelper.greater('lg').value"
|
</div>
|
||||||
:async-key="'stack:' + metaData?.id"
|
<div v-else class="min-w-64"/>
|
||||||
: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"
|
|
||||||
/>
|
|
||||||
</Transition>
|
|
||||||
</div>
|
</div>
|
||||||
<hr/>
|
<hr/>
|
||||||
<div class="flex mt-2">
|
<div class="flex mt-2">
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
// darkVerify.js
|
// darkVerify.js
|
||||||
if (
|
if (
|
||||||
localStorage.getItem('system-theme-mode') === "dark" ||
|
window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
(!localStorage.getItem('system-theme-mode') &&
|
|
||||||
window.matchMedia("(prefers-color-scheme: dark)").matches)
|
|
||||||
) {
|
) {
|
||||||
document.querySelector('html').classList.add('dark');
|
document.querySelector('html').classList.add('dark');
|
||||||
document.querySelector('html').classList.remove('light');
|
document.querySelector('html').classList.remove('light');
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,12 @@ function getInitialMode(): 'light' | 'dark' {
|
||||||
if (document.documentElement.classList.contains('light')) return 'light';
|
if (document.documentElement.classList.contains('light')) return 'light';
|
||||||
// 其次用 localStorage
|
// 其次用 localStorage
|
||||||
const val = localStorage.getItem('system-theme-mode');
|
const val = localStorage.getItem('system-theme-mode');
|
||||||
if (!!val || (val !== 'light' && val !== 'dark'))
|
if (val === 'dark') return 'dark';
|
||||||
return 'light';
|
if (val === 'light') return 'light';
|
||||||
return val;
|
return 'light'; // 默认
|
||||||
}
|
}
|
||||||
return 'light'; // SSR 默认
|
return 'light'; // SSR 默认
|
||||||
};
|
}
|
||||||
|
|
||||||
const useColorModeStore = defineStore('colorMode', {
|
const useColorModeStore = defineStore('colorMode', {
|
||||||
state: () => ({
|
state: () => ({
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue