最近写自研的一个软件产品文档,首次使用了vitepress。看着官方文档,磕磕绊绊的算是完成了一版。比如:
在为文档网站添加访问统计代码时,遇到了些困难。网上搜索和掘金都没有合适的答案。这里介绍我的具体实现,以供需要的同学使用。
一、vitepress的相关配置
为vitepress静态网站增加统计代码,需要在2个地方进行配置:head 和 路由。
1.1 head 配置
我们要增加网站访问统计代码。无论你用的是google还是百度,或者其他第三方统计服务,都需要在head中进行配置。
在 .vitepress/config.ts 文件中,配置如下:
head: [
// ... 其他部分的配置,比如
[
'script',
{},
`
window._hmt = window._hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?abcdefgeggsdfsdf123123";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
`,
],
],
由于google无法访问,又不想花银子,所以这里以某度统计的免费版为例。这里代码中和某度统计官方文档不同的地方,在与第 8 行。(不清楚如何将第8行高亮显示,请知道的同学留言告诉我 :))
window._hmt = window._hmt || [];
官网文档中的实例是:var _hmt = _hmt || []
;
之所以要写入全局变量window中,是为了下面介绍的第2项配置。在第二项配置中,会读取这个 _hmt
变量。如果不存入 window
对象中,则读取不到。
1.2 路由配置
vitepress是基于文件路径的路由,并且构建生成的都是静态的html页面。根据vitepress的官网介绍,vitepress构建的实质上是一个单页面应用(SPA)。
而用户在这个SPA应用中,会访问不同的静态页面。我们必须把他所有不同的访问url都进行统计记录下来。
在SPA应用中,那么仅仅在head部分增加一个js函数来发送访问统计数据到统计平台,就显得不够了。因为这个js函数在spa中,只会执行一次。
既然是spa,那么页面的跳转,就离不开router,我们只需要跟踪路由的变化即可。
1.2.1 主题配置项
我们先来看看主题的主要配置项:
interface EnhanceAppContext {
app: App;
router: Router;
siteData: Ref<SiteData>;
}
interface Theme {
Layout?: Component;
enhanceApp?: (ctx: EnhanceAppContext) => Awaitable<void>;
extends?: Theme;
/**
* @deprecated can be replaced by wrapping layout component
*/
setup?: () => void;
/**
* @deprecated Render not found page by checking `useData().page.value.isNotFound` in Layout instead.
*/
NotFound?: Component;
}
其中:enhanceApp是一个参数为EnhanceAppContext的函数。而EnhanceAppContext的一个属性是Router类型。我们再来看看这个Router:
interface Router {
/**
* Current route.
*/
route: Route;
/**
* Navigate to a new URL.
*/
go: (to?: string) => Promise<void>;
/**
* Called before the route changes. Return `false` to cancel the navigation.
*/
onBeforeRouteChange?: (to: string) => Awaitable<void | boolean>;
/**
* Called before the page component is loaded (after the history state is
* updated). Return `false` to cancel the navigation.
*/
onBeforePageLoad?: (to: string) => Awaitable<void | boolean>;
/**
* Called after the route changes.
*/
onAfterRouteChanged?: (to: string) => Awaitable<void>;
}
从上面的几个接口定义可以看出,EnhanceAppContext的router属性,实际上是vue-router实例的一个代理包装。它有一个当前路由的对象、go方法(跳转方法)和3个事件。根据3个事件的命名,我们可以发现onBeforeRouteChange事件,就是我们需要的方法。即:在路由改变之前进行处理。
1.2.2 自定义路由改变事件
我原来的主题配置文件 ( .vitepress/theme/index.js
) 是这样的:
import './tailwind.postcss';
import DefaultTheme from 'vitepress/theme';
export default { ...DefaultTheme };
我的目的很明确,主要是写文档。vitepress的默认主题我觉着已经够用了。由于对默认的主题样式不熟悉,同时为了增加一些外部的样式以简化文档页面一些自定义的样式,我引入了 tailwind.css
,但是主题文件很简单。只导出了默认的主题。
现在对这个文件内容,做出如下改变:
import './tailwind.postcss';
import DefaultTheme from 'vitepress/theme';
DefaultTheme.enhanceApp = ({ app, router, siteData }) => {
router.onBeforeRouteChange = (to) => {
console.log('路由将改变为: ', to);
if (typeof _hmt !== 'undefined') {
_hmt.push(['_trackPageview', to]);
}
};
};
export default { ...DefaultTheme };
默认主题对象,是不具有enhanceApp属性的(上面的接口定义,该属性是可选的),因此我们手动定义他的内容即可。
在这改代码中 _hmt
就是上面文档介绍的,存入 window
对象的那个对象,如果不存入window,则在build文档时,会发生错误。其 push
方法,就是向某度统计发送当前路径的数据。
当然,这里的 onBeforeRouteChange
事件实现是向某度统计发送url路径。你可以根据实际的统计平台的接口要求,自己实现这一块的逻辑。原理是一样的。
实际运行情况如下:
可以看到,每一次的路由变化,控制台都输出了要跳转的url。都会发送一个 hm.baidu.com/hm.gif?cc=1… 的远程请求。这个请求地址,正是目标统计平台接收数据的地址。
至此,我们实现了为vitepress静态网站增加访问统计代码的功能目标。
原文链接:https://juejin.cn/post/7325722812817309722 作者:FengSir