优化:文章元数据信息开启显示文章阅读数,需要单独提供后端 HTTPS API 服务
This commit is contained in:
@@ -53,6 +53,8 @@ pnpm build
|
||||
|
||||
- [x] 文章元数据信息显示:文章标题下显示作者、发布时间、所属分类、标签列表等信息,可全局配置作者及作者主页信息
|
||||
|
||||
- [x] 已扩展文章阅读数信息,默认已启用,可在 docs/.vitepress/config/theme.ts 中 articleMetadataConfig 配置中关闭(开启需要自行提供并配置好 API 服务,API 服务可参考:[Charles7c/charles7c-api](https://github.com/Charles7c/charles7c-api),目前来看搞起来还有点麻烦,不喜欢折腾的可以直接关闭或更换其他方式提供 API 服务,欢迎提建议)
|
||||
|
||||
- [x] 《我的标签》:模仿语雀标签页风格,另有标签云展示。语雀标签页地址:https://www.yuque.com/r/语雀用户名/tags?tag=
|
||||
|
||||
- [x] 《我的归档》:自定义时间轴,展示历史文章数据。年份前可展示生肖,还可按分类、标签筛选
|
||||
|
@@ -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 |
@@ -19,6 +19,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/g2plot": "^2.4.22",
|
||||
"axios": "^1.2.0",
|
||||
"blueimp-md5": "^2.19.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"fast-glob": "^3.2.12",
|
||||
|
63
pnpm-lock.yaml
generated
63
pnpm-lock.yaml
generated
@@ -3,6 +3,7 @@ lockfileVersion: 5.4
|
||||
specifiers:
|
||||
'@antv/g2plot': ^2.4.22
|
||||
'@arco-design/web-vue': ^2.38.3
|
||||
axios: ^1.2.0
|
||||
blueimp-md5: ^2.19.0
|
||||
dayjs: ^1.11.6
|
||||
fast-glob: ^3.2.12
|
||||
@@ -21,6 +22,7 @@ specifiers:
|
||||
|
||||
dependencies:
|
||||
'@antv/g2plot': 2.4.22
|
||||
axios: 1.2.0
|
||||
blueimp-md5: 2.19.0
|
||||
dayjs: 1.11.6
|
||||
fast-glob: 3.2.12
|
||||
@@ -694,6 +696,10 @@ packages:
|
||||
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
|
||||
dev: true
|
||||
|
||||
/asynckit/0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
dev: false
|
||||
|
||||
/autosize/3.0.21:
|
||||
resolution: {integrity: sha512-xGFj5jTV4up6+fxRwtnAWiCIx/5N0tEnFn5rdhAkK1Lq2mliLMuGJgP5Bf4phck3sHGYrVKpYwugfJ61MSz9nA==}
|
||||
dev: false
|
||||
@@ -707,6 +713,16 @@ packages:
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/axios/1.2.0:
|
||||
resolution: {integrity: sha512-zT7wZyNYu3N5Bu0wuZ6QccIf93Qk1eV8LOewxgjOZFd2DenOs98cJ7+Y6703d0wkaXGY6/nZd4EweJaHz9uzQw==}
|
||||
dependencies:
|
||||
follow-redirects: 1.15.2
|
||||
form-data: 4.0.0
|
||||
proxy-from-env: 1.1.0
|
||||
transitivePeerDependencies:
|
||||
- debug
|
||||
dev: false
|
||||
|
||||
/b-tween/0.3.3:
|
||||
resolution: {integrity: sha512-oEHegcRpA7fAuc9KC4nktucuZn2aS8htymCPcP3qkEGPqiBH+GfqtqoG2l7LxHngg6O0HFM7hOeOYExl1Oz4ZA==}
|
||||
dev: true
|
||||
@@ -832,6 +848,13 @@ packages:
|
||||
color-string: 1.9.1
|
||||
dev: true
|
||||
|
||||
/combined-stream/1.0.8:
|
||||
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
|
||||
engines: {node: '>= 0.8'}
|
||||
dependencies:
|
||||
delayed-stream: 1.0.0
|
||||
dev: false
|
||||
|
||||
/commander/2.20.3:
|
||||
resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==}
|
||||
dev: true
|
||||
@@ -1411,6 +1434,11 @@ packages:
|
||||
robust-predicates: 3.0.1
|
||||
dev: true
|
||||
|
||||
/delayed-stream/1.0.0:
|
||||
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
dev: false
|
||||
|
||||
/detect-browser/5.3.0:
|
||||
resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==}
|
||||
dev: false
|
||||
@@ -1745,6 +1773,16 @@ packages:
|
||||
uglify-js: 2.8.29
|
||||
dev: false
|
||||
|
||||
/follow-redirects/1.15.2:
|
||||
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
|
||||
engines: {node: '>=4.0'}
|
||||
peerDependencies:
|
||||
debug: '*'
|
||||
peerDependenciesMeta:
|
||||
debug:
|
||||
optional: true
|
||||
dev: false
|
||||
|
||||
/follow-redirects/1.5.10:
|
||||
resolution: {integrity: sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==}
|
||||
engines: {node: '>=4.0'}
|
||||
@@ -1760,6 +1798,15 @@ packages:
|
||||
is-callable: 1.2.7
|
||||
dev: false
|
||||
|
||||
/form-data/4.0.0:
|
||||
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
|
||||
engines: {node: '>= 6'}
|
||||
dependencies:
|
||||
asynckit: 0.4.0
|
||||
combined-stream: 1.0.8
|
||||
mime-types: 2.1.35
|
||||
dev: false
|
||||
|
||||
/fs.realpath/1.0.0:
|
||||
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
|
||||
dev: false
|
||||
@@ -2198,6 +2245,18 @@ packages:
|
||||
braces: 3.0.2
|
||||
picomatch: 2.3.1
|
||||
|
||||
/mime-db/1.52.0:
|
||||
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dev: false
|
||||
|
||||
/mime-types/2.1.35:
|
||||
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
|
||||
engines: {node: '>= 0.6'}
|
||||
dependencies:
|
||||
mime-db: 1.52.0
|
||||
dev: false
|
||||
|
||||
/minimatch/3.1.2:
|
||||
resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
|
||||
dependencies:
|
||||
@@ -2368,6 +2427,10 @@ packages:
|
||||
react-is: 16.13.1
|
||||
dev: false
|
||||
|
||||
/proxy-from-env/1.1.0:
|
||||
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
|
||||
dev: false
|
||||
|
||||
/queue-microtask/1.2.3:
|
||||
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
|
||||
|
||||
|
Reference in New Issue
Block a user