Skip to content

路由钩子

Vitepress 提供的 useRouter 有 4 个路由钩子,分别为:

  • onBeforeRouteChange:路由变化前触发,如果在该钩子函数中返回 false,则不会进行路由跳转
  • onBeforePageLoad:页面加载前执行,在 onBeforeRouteChange 之后触发,如果在该钩子函数中返回 false,则不会进行路由跳转
  • onAfterPageLoad:页面加载后执行
  • onAfterRouteChange:路由变化后触发,在 onAfterPageLoad 之后触发

Teek 内置的 4 个评论区组件使用了 onAfterRouteChange 钩子函数,且 vitepress-plugin-permalink 插件分别使用了 onBeforeRouteChangeonAfterRouteChange 两个路由钩子。

如果您也需要使用这些路由钩子,请不要直接这样使用:

ts
router.onAfterRouteChange = (href: string) => {
  // 你的逻辑
};

onAfterRouteChange 是一个函数,您这样使用将会 覆盖 Teek 在该钩子函数的逻辑,因此您需要这样使用:

vue
<script setup lang="ts">
import { useRouter, useData } from "vitepress";

const router = useRouter();
const state = router.state || {};
const stateKey = "xx";

// 防止重复在 router 添加函数
if (!state[stateKey]) {
  const selfOnAfterRouteChange = router.onAfterRouteChange;

  router.onAfterRouteChange = (href: string) => {
    // 调用可能已有的 onAfterRouteChange
    selfOnAfterRouteChange?.(href);

    // 调用自己的函数
    myFunction();
  };

  router.state = { ...state, [stateKey]: true };
}

const myFunction = () => {
  /* */
};
</script>

onBeforeRouteChange 支持返回 false 来阻止路由跳转,因此请这样使用:

vue
<script setup lang="ts">
import { useRouter, useData } from "vitepress";

const router = useRouter();
const state = router.state || {};
const stateKey = "xx";

// 防止重复在 router 添加函数
if (!state[stateKey]) {
  const selfOnAfterRouteChange = router.onAfterRouteChange;

  router.onBeforeRouteChange = (href: string) => {
    // 调用可能已有的 onAfterRouteChange
    const selfResult = selfOnBeforeRouteChange?.(href);
    if (selfResult === false) return false;

    // 调用自己的函数
    myFunction();
  };

  router.state = { ...state, [stateKey]: true };
}

const myFunction = () => {
  /* */
};
</script>

Teek 已经封装了 hooks 文件 useVpRouter,里面分别对 Vitepress 的 router 钩子进行封装,您可以这样使用:

vue
<script setup lang="ts"
import { useVpRouter } from "vitepress-theme-teek";

vpRouter.bindAfterRouteChange("xx", () => {
  // 调用自己的函数
  myFunction();
});

const myFunction = () => {
  /* */
};
</script>

如果您想一次性绑定多个 router 钩子,可以这样使用:

vue
<script setup lang="ts"
import { useVpRouter } from "vitepress-theme-teek";

vpRouter.bindRouterFn("xx", router => {
  router.onBeforeRouteChange = (href: string) => {
    // 调用可能已有的 onAfterRouteChange
    const selfResult = selfOnBeforeRouteChange?.(href);
    if (selfResult === false) return false;

    // 调用自己的函数
    myFunction();
  };

  router.onAfterRouteChange = (href: string) => {
    // 调用可能已有的 onAfterRouteChange
    selfOnAfterRouteChange?.(href);

    // 调用自己的函数
    myFunction();
  };
});

const myFunction = () => {
  /* */
};
</script>