为什么不能直接写在 .md 里
原始写法把 <style> 直接放在 .md 文件中,VitePress 会将其作为全局样式注入。其中的 body { background-image }、:root { --main-color } 以及 .loading 这类裸类名会污染整个站点(SPA 下还会一直存在)。
正确做法是抽成独立组件:背景图通过 onMounted 动态写入 body、onBeforeUnmount 还原,其余样式用 <style scoped> 隔离,只影响当前页面。
实现源码
组件路径:docs/front-end/lib/加载页/加载页.vue
vue
<template>
<div id="loading">
<div class="loading">
<svg width="100%" height="100%">
<text class="loadingIn" x="50%" y="50%" style="dominant-baseline:middle;text-anchor:middle;">Reinforces</text>
</svg>
</div>
</div>
</template>
<script setup>
import { onMounted, onBeforeUnmount } from 'vue'
// 通过 import 让 Vite 解析背景图地址,避免裸 url 写在全局 style 里污染全站 body
import bgMovie from './bg_movie.png'
const timers = []
const after = (fn, ms) => { const t = setTimeout(fn, ms); timers.push(t); return t }
let readyState = false
let prevBg = ''
// 原始加载页脚本中预留的钩子(保留,未自动触发)
// function openLoading() { /* 显示加载层 */ }
// function removeLoading() { /* 关闭加载层 */ }
// document.onreadystatechange = function () {
// if (document.readyState === 'complete') { /* isReady() */ }
// }
onMounted(() => {
// 仅在当前页面给 body 注入加载页背景,离开时还原 —— 不污染全站
prevBg = document.body.style.backgroundImage
document.body.style.backgroundImage = `url(${bgMovie})`
after(() => { readyState = true }, 3500)
})
onBeforeUnmount(() => {
document.body.style.backgroundImage = prevBg
timers.forEach(clearTimeout)
})
</script>
<style scoped>
#loading {
width: 100%;
height: 300px;
overflow: hidden;
position: absolute;
}
.loading {
height: 100%;
width: 100%;
background-image: url('./bg.png');
}
.loadingIn {
font-family: 'roropu';
letter-spacing: 10px;
stroke: #0077ff;
font-size: 5rem;
stroke-width: 0.2rem;
animation: textAnimate 4.5s 1;
animation-fill-mode: forwards;
}
.loadingRpt {
animation: textAnimate 4.5s infinite alternate;
animation-fill-mode: forwards;
}
@keyframes textAnimate {
0% {
stroke-dasharray: 0 15%;
stroke-dashoffset: 20%;
fill: rgba(255, 255, 255, 1);
}
100% {
stroke-dasharray: 15% 0;
stroke-dashoffset: -20%;
fill: rgba(255, 255, 255, 0);
}
}
</style>
<style>
/* 字体全局声明(字体名独立,不影响其他页面) */
@font-face {
font-family: 'roropu';
src: url('./落落の汤圆.ttf');
}
</style>