Skip to content

Commit 940ec1b

Browse files
fix(site): mermaid 跳转后不渲染 — onAfterRouteChange 改订阅器 (#93)
ReadingProgress 与 mermaid 各自直接赋值 router.onAfterRouteChange (单值属性,非事件订阅),后挂载的 ReadingProgress 覆盖了 mermaid 的 回调,导致 SPA 跳转进含 mermaid 的页面时图不渲染、需 F5(首屏走 onMounted 不受影响,所以现象是"直接访问 URL 正常、跳转不显示、 F5 又正常")。 新增 router-hooks.ts 提供 subscribeAfterRouteChange 订阅器(订阅者 集合 + 单 dispatcher,带 try/catch 隔离),mermaid-client 与 ReadingProgress 改用之。治本:未来再加路由切换逻辑不会再互覆盖。 自查:grep 确认全局仅 router-hooks.ts 一处 onAfterRouteChange 赋值; vitepress dev 启动零 error;并行 build SUCCESS (34 task 全建)。 pre-commit update-translation-coverage hook 同步刷新了 README 翻译 覆盖率报告,一并纳入。
1 parent 9a7525d commit 940ec1b

4 files changed

Lines changed: 36 additions & 9 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
---
2121

2222
<!-- COVERAGE_START -->
23-
![English Coverage](https://img.shields.io/badge/en_coverage-97%25-green.svg) 494/510 docs translated
23+
![English Coverage](https://img.shields.io/badge/en_coverage-84%25-green.svg) 494/588 docs translated
2424
<!-- COVERAGE_END -->
2525

2626
## 这是什么项目

site/.vitepress/theme/components/ReadingProgress.vue

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
<script setup lang="ts">
22
import { ref, onMounted, onBeforeUnmount } from 'vue'
3-
import { useRouter } from 'vitepress'
3+
import { subscribeAfterRouteChange } from '../router-hooks'
44
55
// 顶部阅读进度条:滚动时按 scrollTop / (scrollHeight - clientHeight) 算百分比。
66
// brand 渐变 + 钢蓝微光,固定在视口顶部。路由切换 rAF+300ms 双重重算(短页归零坑)。
77
// scroll/resize 用 rAF 合并,一帧最多算一次(比 anatomy 原版无节流更省,审计点名的性能债)。
88
const progress = ref(0)
9-
const router = useRouter()
109
let raf: number | null = null
1110
1211
function update() {
@@ -28,11 +27,11 @@ onMounted(() => {
2827
window.addEventListener('resize', scheduleUpdate, { passive: true })
2928
})
3029
31-
router.onAfterRouteChange = () => {
30+
subscribeAfterRouteChange(() => {
3231
// 路由切换:新页 DOM 立即可测 + 300ms 后(图片/mermaid 撑高)再补一次,防短页/异步内容归零失败
3332
requestAnimationFrame(update)
3433
setTimeout(update, 300)
35-
}
34+
})
3635
3736
onBeforeUnmount(() => {
3837
if (raf !== null) cancelAnimationFrame(raf)

site/.vitepress/theme/mermaid-client.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { nextTick, onMounted } from 'vue'
2-
import { useRouter } from 'vitepress'
2+
import { subscribeAfterRouteChange } from './router-hooks'
33

44
// mermaid 的 API 形状(只取我们用到的两个方法),避免依赖整包类型
55
type MermaidApi = {
@@ -79,9 +79,9 @@ function escapeHtml(s: string) {
7979
}
8080

8181
export function setupMermaid() {
82-
const router = useRouter()
83-
82+
// 用订阅器而非直接赋值 router.onAfterRouteChange:后者是单值属性,
83+
// 会被 ReadingProgress 等组件覆盖,导致 SPA 跳转后 mermaid 不渲染。
8484
// .catch 治「静默失败」:之前 onMounted 调用没接住 reject,加载失败时图直接消失无痕。
8585
onMounted(() => renderMermaidDiagrams().catch((e) => console.error('[mermaid] onMounted 渲染失败', e)))
86-
router.onAfterRouteChange = () => renderMermaidDiagrams().catch((e) => console.error('[mermaid] 路由切换渲染失败', e))
86+
subscribeAfterRouteChange(() => renderMermaidDiagrams().catch((e) => console.error('[mermaid] 路由切换渲染失败', e)))
8787
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { useRouter } from 'vitepress'
2+
3+
// VitePress 的 router.onAfterRouteChange 是单值属性,不是事件订阅:
4+
// 任意组件再赋值就会覆盖前一个。曾经 ReadingProgress 和 mermaid 各自赋值,
5+
// 导致 SPA 跳转后 mermaid 不渲染(首屏 onMounted 路径正常,跳转路径被覆盖)。
6+
// 这里包一层订阅器:第一次订阅时安装一个 dispatcher,之后所有订阅者共享。
7+
type RouteHandler = (href: string) => void
8+
9+
const subscribers = new Set<RouteHandler>()
10+
let installed = false
11+
12+
export function subscribeAfterRouteChange(fn: RouteHandler): void {
13+
subscribers.add(fn)
14+
if (installed) return
15+
// 必须在 setup 上下文调用(mermaid 的 setupMermaid / 各组件 setup 均满足)。
16+
const router = useRouter()
17+
router.onAfterRouteChange = (href: string) => {
18+
for (const fn of subscribers) {
19+
try {
20+
fn(href)
21+
} catch (e) {
22+
// 单个订阅者抛错不能连累其它订阅者(否则 mermaid 渲染失败会让进度条也不更新)。
23+
console.error('[router-hook] onAfterRouteChange 订阅者抛错', e)
24+
}
25+
}
26+
}
27+
installed = true
28+
}

0 commit comments

Comments
 (0)