Skip to content

Commit

Permalink
feat(vitepress): 添加访客统计
Browse files Browse the repository at this point in the history
  • Loading branch information
maomao1996 committed Apr 9, 2024
1 parent 388ece7 commit e5c23bc
Show file tree
Hide file tree
Showing 8 changed files with 159 additions and 5 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ export default defineConfig({
prev: '上一篇',
next: '下一篇',
},

visitor: {
badgeId: 'maomao1996.vitepress-nav-template',
},
},

vite: {
Expand Down
67 changes: 67 additions & 0 deletions docs/.vitepress/theme/components/MDocFooter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script setup lang="ts">
import { inject, Ref, computed } from 'vue'
import { useData } from 'vitepress'
import { useSidebar } from 'vitepress/theme'
import { usePageId } from '../composables'
const DEV = inject<Ref<boolean>>('DEV')
const { theme } = useData()
const { footer, visitor } = theme.value
const { hasSidebar } = useSidebar()
const pageId = usePageId()
const isDocFooterVisible = computed(() => {
return !DEV || footer.message || footer.copyright || visitor.badgeId
})
</script>

<template>
<div v-if="isDocFooterVisible" v-show="hasSidebar" class="m-doc-footer">
<div class="m-doc-footer-message">
<img
v-if="!DEV && visitor"
class="visitor"
:src="`https://visitor-badge.laobi.icu/badge?page_id=${visitor.badgeId}.${pageId}`"
title="当前页面累计访问数"
onerror="this.style.display='none'"
/>
<p v-if="footer?.message">{{ footer.message }}</p>
</div>
<p class="m-doc-footer-copyright" v-if="footer?.copyright">
{{ footer.copyright }}
</p>
</div>
</template>

<style scoped>
.m-doc-footer {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 24px;
border-top: 1px solid var(--vp-c-gutter);
padding: 32px 24px 0;
line-height: 24px;
font-size: 14px;
font-weight: 500;
color: var(--vp-c-text-2);
}
.m-doc-footer-message,
.m-doc-footer-copyright {
display: flex;
align-items: center;
}
.visitor {
margin-right: 8px;
}
@media (max-width: 414px) {
.visitor {
display: none;
}
}
</style>
17 changes: 16 additions & 1 deletion docs/.vitepress/theme/components/MLayout.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { useData } from 'vitepress'
import DefaultTheme from 'vitepress/theme'
import { nextTick, provide } from 'vue'
import MNavVisitor from './MNavVisitor.vue'
import MDocFooter from './MDocFooter.vue'
const { Layout } = DefaultTheme
const { isDark } = useData()
Expand Down Expand Up @@ -42,5 +45,17 @@ provide('toggle-appearance', async ({ clientX: x, clientY: y }: MouseEvent) => {
</script>

<template>
<Layout v-bind="$attrs" />
<Layout v-bind="$attrs">
<!--
相关插槽
https://vitepress.dev/zh/guide/extending-default-theme#layout-slots
https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/Layout.vue
-->
<template #nav-bar-title-after>
<MNavVisitor />
</template>
<template #doc-after>
<MDocFooter />
</template>
</Layout>
</template>
29 changes: 29 additions & 0 deletions docs/.vitepress/theme/components/MNavVisitor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script setup lang="ts">
import { useData } from 'vitepress'
import { inject, Ref } from 'vue'
const DEV = inject<Ref<boolean>>('DEV')
const { theme } = useData()
const { visitor } = theme.value
</script>

<template>
<img
v-if="!DEV && visitor"
class="visitor"
:src="`https://visitor-badge.laobi.icu/badge?page_id=${visitor.badgeId}`"
onerror="this.style.display='none'"
/>
</template>

<style scoped>
.visitor {
margin-left: 8px;
}
@media (min-width: 768px) and (max-width: 920px) {
.visitor {
display: none;
}
}
</style>
3 changes: 3 additions & 0 deletions docs/.vitepress/theme/composables/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export * from './useFormatPath'
export * from './useMediumZoom'
export * from './usePageId'
12 changes: 12 additions & 0 deletions docs/.vitepress/theme/composables/useFormatPath.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useData, useRoute } from 'vitepress'
import { computed } from 'vue'

/**
* 对 route.path 进行格式化,统一 github pages 和其他部署平台的 route.path
*/
export function useFormatPath() {
const { site } = useData()
const route = useRoute()

return computed(() => route.path.replace(site.value.base.replace(/\/$/, ''), ''))
}
14 changes: 14 additions & 0 deletions docs/.vitepress/theme/composables/usePageId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { computed } from 'vue'
import { useData } from 'vitepress'

import { useFormatPath } from '../composables'

/**
* 获取当前页面的 pageId 用于页面统计和评论(默认为 route.path)
*/
export function usePageId() {
const { frontmatter } = useData()
const formatPath = useFormatPath()

return computed(() => frontmatter.value.pageId || formatPath.value)
}
18 changes: 14 additions & 4 deletions env.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
/// <reference types="vitepress/client" />

declare module '*.vue' {
import { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
import { DefaultTheme } from 'vitepress'

declare module 'vitepress' {
export namespace DefaultTheme {
export interface Config {
/**
* 访客统计配置
*/
visitor?: {
/** 统计 id(单独页面的统计会作为前缀使用)*/
badgeId: string
}
}
}
}

0 comments on commit e5c23bc

Please sign in to comment.