优化:文章元数据信息开启显示文章阅读数,需要单独提供后端 HTTPS API 服务
This commit is contained in:
@@ -47,7 +47,7 @@ export const themeConfig: DefaultTheme.Config = {
|
||||
articleMetadataConfig: {
|
||||
author: '查尔斯', // 文章全局默认作者名称
|
||||
authorLink: '/about/me', // 点击作者名时默认跳转的链接
|
||||
showPv: false // 是否显示文章阅读数, 需配置好相应后端API接口
|
||||
showPv: true // 是否显示文章阅读数, 需要在 docs/.vitepress/theme/api/config.js 及 interface.js 配置好相应 API 接口
|
||||
},
|
||||
// 自定义扩展: 文章版权配置
|
||||
copyrightConfig: {
|
||||
|
24
docs/.vitepress/theme/api/config.js
Normal file
24
docs/.vitepress/theme/api/config.js
Normal file
@@ -0,0 +1,24 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const createBaseInstance = () => {
|
||||
const instance = axios.create({
|
||||
baseURL: 'https://api.charles7c.top/blog',
|
||||
timeout: 3000
|
||||
})
|
||||
instance.interceptors.request.use(handleRequest, handleError)
|
||||
instance.interceptors.response.use(handleResponse, handleError)
|
||||
return instance
|
||||
}
|
||||
export const request = createBaseInstance()
|
||||
|
||||
function handleError(e) {
|
||||
throw e
|
||||
}
|
||||
|
||||
function handleRequest(request) {
|
||||
return request;
|
||||
}
|
||||
|
||||
function handleResponse(response) {
|
||||
return response.data
|
||||
}
|
3
docs/.vitepress/theme/api/index.js
Normal file
3
docs/.vitepress/theme/api/index.js
Normal file
@@ -0,0 +1,3 @@
|
||||
export * from './interface'
|
||||
|
||||
export { default } from './interface'
|
17
docs/.vitepress/theme/api/interface.js
Normal file
17
docs/.vitepress/theme/api/interface.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import { request } from './config'
|
||||
|
||||
export const getPv = (id, call) => {
|
||||
request.get(`/pv/${id}`, {}).then(result => {
|
||||
call(process(result))
|
||||
})
|
||||
}
|
||||
|
||||
function process(result) {
|
||||
if (result.code === 200) {
|
||||
return result.data
|
||||
} else {
|
||||
console.log(result.msg)
|
||||
}
|
||||
}
|
||||
|
||||
export default { getPv }
|
@@ -14,11 +14,11 @@
|
||||
</span>
|
||||
<time class="meta-content" :datetime="date.toISOString()" :title="dayjs().to(dayjs(date))">{{ date.toLocaleString('zh', {year: 'numeric', month: 'numeric', day: 'numeric', hour: 'numeric', minute: 'numeric'}) }}</time>
|
||||
</div>
|
||||
<div class="meta-item" v-if="theme.articleMetadataConfig?.showPv ?? false">
|
||||
<div class="meta-item" v-if="showPv">
|
||||
<span class="meta-icon pv">
|
||||
<svg role="img" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><title>阅读数</title><path d="M942.2 486.2C847.4 286.5 704.1 186 512 186c-192.2 0-335.4 100.5-430.2 300.3-7.7 16.2-7.7 35.2 0 51.5C176.6 737.5 319.9 838 512 838c192.2 0 335.4-100.5 430.2-300.3 7.7-16.2 7.7-35 0-51.5zM512 766c-161.3 0-279.4-81.8-362.7-254C232.6 339.8 350.7 258 512 258c161.3 0 279.4 81.8 362.7 254C791.5 684.2 673.4 766 512 766z"></path><path d="M508 336c-97.2 0-176 78.8-176 176s78.8 176 176 176 176-78.8 176-176-78.8-176-176-176z m0 288c-61.9 0-112-50.1-112-112s50.1-112 112-112 112 50.1 112 112-50.1 112-112 112z"></path></svg>
|
||||
</span>
|
||||
<span id="pv" class="meta-content"></span>
|
||||
<span id="pv" class="meta-content">0</span>
|
||||
</div>
|
||||
<div class="meta-item" v-if="showCategory">
|
||||
<span class="meta-icon category">
|
||||
@@ -46,8 +46,9 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { reactive, toRefs } from 'vue'
|
||||
import { reactive, toRefs, onMounted } from 'vue'
|
||||
import { useData } from 'vitepress'
|
||||
import md5 from 'blueimp-md5'
|
||||
import dayjs from 'dayjs'
|
||||
import 'dayjs/locale/zh-cn'
|
||||
import relativeTime from 'dayjs/plugin/relativeTime'
|
||||
@@ -66,16 +67,26 @@ const props = defineProps({
|
||||
})
|
||||
|
||||
// 初始化文章元数据信息
|
||||
const { theme } = useData()
|
||||
const { theme, page } = useData()
|
||||
const data = reactive({
|
||||
author: props.article?.author ?? theme.value.articleMetadataConfig.author,
|
||||
authorLink: props.article?.authorLink ?? theme.value.articleMetadataConfig.authorLink,
|
||||
showPv: theme.value.articleMetadataConfig?.showPv ?? false,
|
||||
date: new Date(props.article.date),
|
||||
categories: props.article?.categories ?? [],
|
||||
tags: props.article?.tags ?? [],
|
||||
showCategory: props.showCategory
|
||||
})
|
||||
const { author, authorLink, date, toDate, categories, tags, showCategory } = toRefs(data)
|
||||
const { author, authorLink, showPv, date, toDate, categories, tags, showCategory } = toRefs(data)
|
||||
|
||||
if (data.showPv) {
|
||||
// 记录并获取文章阅读数(使用文章标题 + 发布时间生成 MD5 值,作为文章的唯一标识)
|
||||
onMounted(() => {
|
||||
$api.getPv(md5(props.article.title + props.article.date), function(data) {
|
||||
document.getElementById("pv").innerText = data
|
||||
})
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@@ -2,6 +2,8 @@ import DefaultTheme from 'vitepress/theme'
|
||||
import MyLayout from './MyLayout.vue'
|
||||
import './styles/vars.css'
|
||||
import './styles/custom.css'
|
||||
import axios from 'axios'
|
||||
import api from './api/index'
|
||||
|
||||
export default {
|
||||
...DefaultTheme,
|
||||
@@ -10,6 +12,12 @@ export default {
|
||||
// extend default theme custom behaviour.
|
||||
DefaultTheme.enhanceApp(ctx)
|
||||
|
||||
// 全局挂载 API 接口
|
||||
ctx.app.config.globalProperties.$http = axios
|
||||
if (typeof window !== 'undefined') {
|
||||
window.$api = api
|
||||
}
|
||||
|
||||
// register your custom global components
|
||||
// ctx.app.component('MyGlobalComponent' /* ... */)
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 194 KiB After Width: | Height: | Size: 195 KiB |
Binary file not shown.
Before Width: | Height: | Size: 229 KiB After Width: | Height: | Size: 229 KiB |
Reference in New Issue
Block a user