惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hugging Face - Blog
Hugging Face - Blog
Microsoft Azure Blog
Microsoft Azure Blog
月光博客
月光博客
S
Securelist
J
Java Code Geeks
Recorded Future
Recorded Future
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
M
MIT News - Artificial intelligence
S
Secure Thoughts
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Docker
Martin Fowler
Martin Fowler
The Last Watchdog
The Last Watchdog
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
Vercel News
Vercel News
O
OpenAI News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
PCI Perspectives
PCI Perspectives
N
News and Events Feed by Topic
H
Heimdal Security Blog
SecWiki News
SecWiki News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 【当耐特】
T
Troy Hunt's Blog
L
LINUX DO - 最新话题
Hacker News: Ask HN
Hacker News: Ask HN
Hacker News - Newest:
Hacker News - Newest: "LLM"
N
Netflix TechBlog - Medium
A
Arctic Wolf
The Hacker News
The Hacker News
I
Intezer
S
Schneier on Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Apple Machine Learning Research
Apple Machine Learning Research
L
Lohrmann on Cybersecurity
宝玉的分享
宝玉的分享
P
Privacy & Cybersecurity Law Blog
Stack Overflow Blog
Stack Overflow Blog
T
Tor Project blog
小众软件
小众软件
Simon Willison's Weblog
Simon Willison's Weblog
The Cloudflare Blog
Jina AI
Jina AI

Hyde Blog

Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog 关于我 关于我 Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog
Hyde Blog
Hyde · 2025-10-05 · via Hyde Blog

路由切换遮罩 ​

创建组件 ​

  • docs\.vitepress\theme\components下创建\RouteSwitchingLoading.vue组件

vue

<template>
  <!-- Transition 控制整个遮罩的进入/离开 -->
  <Transition name="fade" mode="out-in">
    <div v-show="isTransitioning" class="transition-mask">
      <div class="loader">
        <div class="spinner"></div>
        <p>拼命加载中...</p>
      </div>
    </div>
  </Transition>
</template>

<script setup>
import { onBeforeMount, onMounted, ref } from "vue";
import { useRouter } from "vitepress";

const router = useRouter();
const isTransitioning = ref(false);
let transitionStart = 0;

// 保存 VitePress 内部默认的路由钩子
const originalBeforeRouteChange = router.onBeforeRouteChange;
const originalAfterRouteChange = router.onAfterRouteChange;

// 路由开始切换时
const handleRouteStart = () => {
  transitionStart = Date.now();
  isTransitioning.value = true;
};

// 路由完成切换时
const handleRouteComplete = () => {
  const elapsed = Date.now() - transitionStart;
  // 确保动画至少显示 600ms,提升视觉体验
  const delay = Math.max(0, 600 - elapsed);

  setTimeout(() => {
    isTransitioning.value = false;
  }, delay);
};

// 重写路由切换前的钩子
router.onBeforeRouteChange = (to) => {
  originalBeforeRouteChange && originalBeforeRouteChange(to);
  handleRouteStart();
};

// 重写路由切换后的钩子
router.onAfterRouteChange = (to) => {
  originalAfterRouteChange && originalAfterRouteChange(to);
  handleRouteComplete();
};

// 首次加载时显示遮罩
onBeforeMount(handleRouteStart);
onMounted(handleRouteComplete);
</script>

<style scoped>
/* 过渡遮罩层样式,使用 scoped 避免样式污染 */
.transition-mask {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column; /* 让加载图标和文字垂直排列 */
  justify-content: center;
  align-items: center;
  background: rgba(255, 255, 255, 0.95); /* 调整透明度,增强遮罩效果 */
  z-index: 9999;
}

.loader {
  text-align: center;
}

.spinner {
  width: 50px; /* 增大加载图标,更醒目 */
  height: 50px;
  margin: 0 auto 12px;
  border: 5px solid #f3f3f3;
  border-top: 5px solid var(--vp-c-brand-1);
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

/* ✅ 添加过渡类 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.25s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

注册组件 ​

docs\.vitepress\theme\components\TeekLayoutProvider.vue中注册组件

vue

<script setup lang="ts" name="TeekLayoutProvider">
// 路由切换loading组件
import RouteSwitchingLoading from "./RouteSwitchingLoading.vue"; 
</script>

<template>
  <Teek.Layout>
    <template #layout-top>
      <!-- 路由切换loading组件 -->
      <RouteSwitchingLoading/>
      <!-- 其他组件 -->
    </template>
  </Teek.Layout>
</template>