feat:增加博客统计组件
This commit is contained in:
@@ -52,7 +52,8 @@ export default withMermaid({
|
||||
{ text: 'SpringBoot Starter原理', link: '/Web-Backend/SpringBoot/SpringBootStarter' },
|
||||
{ text: 'SpringBoot Bean简介', link: '/Web-Backend/SpringBoot/SpringBootBean' },
|
||||
{ text: 'SpringBoot3原生镜像', link: '/Web-Backend/SpringBoot/SpringBoot3-GraalVM' },
|
||||
{ text: 'SpingBoot技巧', link: '/Web-Backend/SpringBoot/SpingBoot-Skills' }
|
||||
{ text: 'SpingBoot技巧', link: '/Web-Backend/SpringBoot/SpingBoot-Skills' },
|
||||
{ text: 'SpringBoot Common', link: '/Web-Backend/SpringBoot/SpringBoot-Common' }
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -125,7 +126,8 @@ export default withMermaid({
|
||||
{ text: 'SpringBoot Starter原理', link: '/Web-Backend/SpringBoot/SpringBootStarter' },
|
||||
{ text: 'SpringBoot Bean简介', link: '/Web-Backend/SpringBoot/SpringBootBean' },
|
||||
{ text: 'SpringBoot3原生镜像', link: '/Web-Backend/SpringBoot/SpringBoot3-GraalVM' },
|
||||
{ text: 'SpingBoot技巧', link: '/Web-Backend/SpringBoot/SpingBoot-Skills' }
|
||||
{ text: 'SpingBoot技巧', link: '/Web-Backend/SpringBoot/SpingBoot-Skills' },
|
||||
{ text: 'SpringBoot Common', link: '/Web-Backend/SpringBoot/SpringBoot-Common' }
|
||||
]
|
||||
},
|
||||
{ text: 'FastAPI',
|
||||
|
||||
66
docs/.vitepress/theme/components/ArticleMetadata.vue
Normal file
66
docs/.vitepress/theme/components/ArticleMetadata.vue
Normal file
@@ -0,0 +1,66 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed, ref, onMounted } from 'vue'
|
||||
import { countWord } from '../utils/functions'
|
||||
|
||||
const wordCount = ref(0)
|
||||
const imageCount = ref(0)
|
||||
|
||||
const wordTime = computed(() => {
|
||||
return ((wordCount.value / 275) * 60)
|
||||
})
|
||||
|
||||
const imageTime = computed(() => {
|
||||
const n = imageCount.value
|
||||
if (imageCount.value <= 10) {
|
||||
// 等差数列求和
|
||||
return n * 13 + (n * (n - 1)) / 2
|
||||
}
|
||||
return 175 + (n - 10) * 3
|
||||
})
|
||||
|
||||
// 阅读时间
|
||||
const readTime = computed(() => {
|
||||
return Math.ceil((wordTime.value + imageTime.value) / 60)
|
||||
})
|
||||
|
||||
|
||||
function analyze() {
|
||||
document.querySelectorAll('.meta-des').forEach(v => v.remove())
|
||||
const docDomContainer = window.document.querySelector('#VPContent')
|
||||
const imgs = docDomContainer?.querySelectorAll<HTMLImageElement>(
|
||||
'.content-container .main img'
|
||||
)
|
||||
imageCount.value = imgs?.length || 0
|
||||
const words = docDomContainer?.querySelector('.content-container .main')?.textContent || ''
|
||||
wordCount.value = countWord(words)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 初始化时执行一次
|
||||
analyze()
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="word">
|
||||
<p>
|
||||
<svg t="1724571760788" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6125" width="16" height="16"><path d="M204.8 0h477.866667l273.066666 273.066667v614.4c0 75.093333-61.44 136.533333-136.533333 136.533333H204.8c-75.093333 0-136.533333-61.44-136.533333-136.533333V136.533333C68.266667 61.44 129.706667 0 204.8 0z m307.2 607.573333l68.266667 191.146667c13.653333 27.306667 54.613333 27.306667 61.44 0l102.4-273.066667c6.826667-20.48 0-34.133333-20.48-40.96s-34.133333 0-40.96 13.653334l-68.266667 191.146666-68.266667-191.146666c-13.653333-27.306667-54.613333-27.306667-68.266666 0l-68.266667 191.146666-68.266667-191.146666c-6.826667-13.653333-27.306667-27.306667-47.786666-20.48s-27.306667 27.306667-20.48 47.786666l102.4 273.066667c13.653333 27.306667 54.613333 27.306667 61.44 0l75.093333-191.146667z" fill="#1890FF" p-id="6126"></path><path d="M682.666667 0l273.066666 273.066667h-204.8c-40.96 0-68.266667-27.306667-68.266666-68.266667V0z" fill="#52C41A" p-id="6127"></path></svg>
|
||||
字数: {{ wordCount }} 字
|
||||
<svg t="1724572797268" class="icon" viewBox="0 0 1060 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="15031" width="16" height="16"><path d="M556.726857 0.256A493.933714 493.933714 0 0 0 121.929143 258.998857L0 135.021714v350.390857h344.649143L196.205714 334.482286a406.820571 406.820571 0 1 1-15.908571 312.649143H68.937143A505.819429 505.819429 0 1 0 556.726857 0.256z m-79.542857 269.531429v274.907428l249.197714 150.966857 42.422857-70.070857-212.114285-129.389714V269.787429h-79.542857z" fill="#FA8C16" p-id="15032"></path></svg>
|
||||
时长: {{ readTime }} 分钟
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.word {
|
||||
color: var(--vp-c-text-2);
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: inline-block;
|
||||
transform: translate(0px , 2px);
|
||||
}
|
||||
</style>
|
||||
@@ -1,5 +1,6 @@
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import Confetti from "./components/Confetti.vue";
|
||||
import ArticleMetadata from "./components/ArticleMetadata.vue"
|
||||
import type { EnhanceAppContext } from 'vitepress'
|
||||
import { onMounted, watch, nextTick } from 'vue'
|
||||
import { useRoute } from 'vitepress'
|
||||
@@ -27,5 +28,6 @@ export default {
|
||||
},
|
||||
enhanceApp({ app }: EnhanceAppContext) {
|
||||
app.component("Confetti", Confetti);
|
||||
app.component("ArticleMetadata", ArticleMetadata);
|
||||
},
|
||||
};
|
||||
|
||||
19
docs/.vitepress/theme/utils/functions.ts
Normal file
19
docs/.vitepress/theme/utils/functions.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
const pattern
|
||||
= /[a-zA-Z0-9_\u0392-\u03C9\u00C0-\u00FF\u0600-\u06FF\u0400-\u04FF]+|[\u4E00-\u9FFF\u3400-\u4DBF\uF900-\uFAFF\u3040-\u309F\uAC00-\uD7AF]+/g
|
||||
|
||||
export function countWord(data: string) {
|
||||
const m = data.match(pattern)
|
||||
let count = 0
|
||||
if (!m) {
|
||||
return 0
|
||||
}
|
||||
for (let i = 0; i < m.length; i += 1) {
|
||||
if (m[i].charCodeAt(0) >= 0x4E00) {
|
||||
count += m[i].length
|
||||
}
|
||||
else {
|
||||
count += 1
|
||||
}
|
||||
}
|
||||
return count
|
||||
}
|
||||
Reference in New Issue
Block a user