Skip to content
Reinforces

为什么不能直接写在 .md 里

原始写法把 <style> 直接放在 .md 文件中,VitePress 会将其作为全局样式注入。其中的 body { background-image }:root { --main-color } 以及 .loading 这类裸类名会污染整个站点(SPA 下还会一直存在)。

正确做法是抽成独立组件:背景图通过 onMounted 动态写入 bodyonBeforeUnmount 还原,其余样式用 <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>