@sugarat/theme 0.1.49 → 0.1.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/node.d.ts +1 -1
- package/node.js +23 -19
- package/package.json +23 -23
- package/src/components/BlogAlert.vue +17 -17
- package/src/components/BlogApp.vue +81 -49
- package/src/components/BlogArticleAnalyze.vue +56 -57
- package/src/components/BlogComment.vue +53 -50
- package/src/components/BlogDocCover.vue +4 -4
- package/src/components/BlogFriendLink.vue +40 -31
- package/src/components/BlogHomeBanner.vue +22 -16
- package/src/components/BlogHomeOverview.vue +20 -20
- package/src/components/BlogHomeTags.vue +49 -40
- package/src/components/BlogHotArticle.vue +43 -36
- package/src/components/BlogImagePreview.vue +7 -5
- package/src/components/BlogItem.vue +42 -43
- package/src/components/BlogList.vue +46 -42
- package/src/components/BlogPopover.vue +41 -39
- package/src/components/BlogRecommendArticle.vue +58 -48
- package/src/components/BlogSearch.vue +143 -145
- package/src/components/UserWorks.vue +214 -210
- package/src/composables/config/blog.ts +7 -5
- package/src/composables/config/index.ts +33 -31
- package/src/constants/svg.ts +2 -2
- package/src/index.ts +1 -2
- package/src/node.ts +2 -2
- package/src/styles/scss/global.scss +0 -5
- package/src/utils/client/index.ts +9 -8
- package/src/utils/node/genFeed.ts +8 -7
- package/src/utils/node/index.ts +8 -6
- package/src/utils/node/mdPlugins.ts +29 -22
- package/src/utils/node/theme.ts +16 -13
- package/src/utils/node/vitePlugins.ts +7 -6
- package/types/vue-shim.d.ts +1 -1
package/node.d.ts
CHANGED
package/node.js
CHANGED
|
@@ -197,7 +197,7 @@ var tabsPlugin = (md) => {
|
|
|
197
197
|
};
|
|
198
198
|
|
|
199
199
|
// src/utils/node/index.ts
|
|
200
|
-
var
|
|
200
|
+
var import_node_child_process = require("child_process");
|
|
201
201
|
|
|
202
202
|
// src/utils/client/index.ts
|
|
203
203
|
function formatDate(d, fmt = "yyyy-MM-dd hh:mm:ss") {
|
|
@@ -211,7 +211,7 @@ function formatDate(d, fmt = "yyyy-MM-dd hh:mm:ss") {
|
|
|
211
211
|
"m+": d.getMinutes(),
|
|
212
212
|
"s+": d.getSeconds(),
|
|
213
213
|
"q+": Math.floor((d.getMonth() + 3) / 3),
|
|
214
|
-
S: d.getMilliseconds()
|
|
214
|
+
"S": d.getMilliseconds()
|
|
215
215
|
};
|
|
216
216
|
if (/(y+)/.test(fmt)) {
|
|
217
217
|
fmt = fmt.replace(
|
|
@@ -258,7 +258,7 @@ function getDefaultTitle(content) {
|
|
|
258
258
|
function getFileBirthTime(url) {
|
|
259
259
|
let date = new Date();
|
|
260
260
|
try {
|
|
261
|
-
const infoStr = (0,
|
|
261
|
+
const infoStr = (0, import_node_child_process.spawnSync)("git", ["log", "-1", '--pretty="%ci"', url]).stdout?.toString().replace(/["']/g, "").trim();
|
|
262
262
|
if (infoStr) {
|
|
263
263
|
date = new Date(infoStr);
|
|
264
264
|
}
|
|
@@ -277,11 +277,11 @@ function aliasObjectToArray(obj) {
|
|
|
277
277
|
}));
|
|
278
278
|
}
|
|
279
279
|
var EXTERNAL_URL_RE = /^[a-z]+:/i;
|
|
280
|
-
function joinPath(base,
|
|
281
|
-
return `${base}${
|
|
280
|
+
function joinPath(base, path4) {
|
|
281
|
+
return `${base}${path4}`.replace(/\/+/g, "/");
|
|
282
282
|
}
|
|
283
|
-
function withBase(base,
|
|
284
|
-
return EXTERNAL_URL_RE.test(
|
|
283
|
+
function withBase(base, path4) {
|
|
284
|
+
return EXTERNAL_URL_RE.test(path4) || path4.startsWith(".") ? path4 : joinPath(base, path4);
|
|
285
285
|
}
|
|
286
286
|
|
|
287
287
|
// src/utils/node/mdPlugins.ts
|
|
@@ -327,7 +327,7 @@ function assignMermaid(config) {
|
|
|
327
327
|
...aliasObjectToArray({
|
|
328
328
|
...config.vite.resolve.alias,
|
|
329
329
|
"cytoscape/dist/cytoscape.umd.js": "cytoscape/dist/cytoscape.esm.js",
|
|
330
|
-
mermaid: "mermaid/dist/mermaid.esm.mjs"
|
|
330
|
+
"mermaid": "mermaid/dist/mermaid.esm.mjs"
|
|
331
331
|
}),
|
|
332
332
|
{ find: /^dayjs\/(.*).js/, replacement: "dayjs/esm/$1" }
|
|
333
333
|
];
|
|
@@ -360,10 +360,11 @@ function supportRunExtendsPlugin(config) {
|
|
|
360
360
|
}
|
|
361
361
|
|
|
362
362
|
// src/utils/node/theme.ts
|
|
363
|
+
var import_node_fs = __toESM(require("fs"));
|
|
364
|
+
var import_node_path = __toESM(require("path"));
|
|
365
|
+
var import_node_process = __toESM(require("process"));
|
|
363
366
|
var import_fast_glob = __toESM(require("fast-glob"));
|
|
364
367
|
var import_gray_matter = __toESM(require("gray-matter"));
|
|
365
|
-
var import_fs = __toESM(require("fs"));
|
|
366
|
-
var import_path = __toESM(require("path"));
|
|
367
368
|
function patchDefaultThemeSideBar(cfg) {
|
|
368
369
|
return cfg?.blog !== false && cfg?.recommend !== false ? {
|
|
369
370
|
sidebar: [
|
|
@@ -376,27 +377,27 @@ function patchDefaultThemeSideBar(cfg) {
|
|
|
376
377
|
}
|
|
377
378
|
var pageMap = /* @__PURE__ */ new Map();
|
|
378
379
|
function getArticles(cfg) {
|
|
379
|
-
const srcDir = cfg?.srcDir ||
|
|
380
|
+
const srcDir = cfg?.srcDir || import_node_process.default.argv.slice(2)?.[1] || ".";
|
|
380
381
|
const files = import_fast_glob.default.sync(`${srcDir}/**/*.md`, { ignore: ["node_modules"] });
|
|
381
382
|
const data = files.map((v) => {
|
|
382
383
|
let route = v.replace(".md", "");
|
|
383
384
|
if (route.startsWith("./")) {
|
|
384
385
|
route = route.replace(
|
|
385
386
|
new RegExp(
|
|
386
|
-
`^\\.\\/${
|
|
387
|
+
`^\\.\\/${import_node_path.default.join(srcDir, "/").replace(new RegExp(`\\${import_node_path.default.sep}`, "g"), "/")}`
|
|
387
388
|
),
|
|
388
389
|
""
|
|
389
390
|
);
|
|
390
391
|
} else {
|
|
391
392
|
route = route.replace(
|
|
392
393
|
new RegExp(
|
|
393
|
-
`^${
|
|
394
|
+
`^${import_node_path.default.join(srcDir, "/").replace(new RegExp(`\\${import_node_path.default.sep}`, "g"), "/")}`
|
|
394
395
|
),
|
|
395
396
|
""
|
|
396
397
|
);
|
|
397
398
|
}
|
|
398
399
|
pageMap.set(`/${route}`, v);
|
|
399
|
-
const fileContent =
|
|
400
|
+
const fileContent = import_node_fs.default.readFileSync(v, "utf-8");
|
|
400
401
|
const { data: frontmatter, excerpt } = (0, import_gray_matter.default)(fileContent, {
|
|
401
402
|
excerpt: true
|
|
402
403
|
});
|
|
@@ -452,11 +453,14 @@ function patchVPThemeConfig(cfg, vpThemeConfig = {}) {
|
|
|
452
453
|
}
|
|
453
454
|
|
|
454
455
|
// src/utils/node/vitePlugins.ts
|
|
456
|
+
var import_node_path3 = __toESM(require("path"));
|
|
457
|
+
var import_node_child_process2 = require("child_process");
|
|
458
|
+
var import_node_process2 = __toESM(require("process"));
|
|
455
459
|
var import_vitepress_plugin_pagefind = require("vitepress-plugin-pagefind");
|
|
456
460
|
|
|
457
461
|
// src/utils/node/genFeed.ts
|
|
458
|
-
var
|
|
459
|
-
var
|
|
462
|
+
var import_node_path2 = __toESM(require("path"));
|
|
463
|
+
var import_node_fs2 = __toESM(require("fs"));
|
|
460
464
|
var import_feed = require("feed");
|
|
461
465
|
async function genFeed(config) {
|
|
462
466
|
const blogCfg = config.userConfig.themeConfig.blog;
|
|
@@ -499,7 +503,7 @@ async function genFeed(config) {
|
|
|
499
503
|
let html;
|
|
500
504
|
const filepath = pageMap.get(route);
|
|
501
505
|
if (filepath) {
|
|
502
|
-
const fileContent =
|
|
506
|
+
const fileContent = import_node_fs2.default.readFileSync(filepath, "utf-8");
|
|
503
507
|
html = mdRender.render(fileContent);
|
|
504
508
|
}
|
|
505
509
|
feed.addItem({
|
|
@@ -518,8 +522,8 @@ async function genFeed(config) {
|
|
|
518
522
|
});
|
|
519
523
|
}
|
|
520
524
|
const RSSFilename = filename || "feed.rss";
|
|
521
|
-
const RSSFile =
|
|
522
|
-
(0,
|
|
525
|
+
const RSSFile = import_node_path2.default.join(config.outDir, RSSFilename);
|
|
526
|
+
(0, import_node_fs2.writeFileSync)(RSSFile, feed.rss2());
|
|
523
527
|
console.log("\u{1F389} RSS generated", RSSFilename);
|
|
524
528
|
console.log("rss filepath:", RSSFile);
|
|
525
529
|
console.log("rss url:", `${baseUrl}${config.site.base + RSSFilename}`);
|
package/package.json
CHANGED
|
@@ -1,8 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sugarat/theme",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.50",
|
|
4
4
|
"description": "简约风的 Vitepress 博客主题,sugarat vitepress blog theme",
|
|
5
|
-
"
|
|
5
|
+
"author": "sugar",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"homepage": "https://theme.sugarat.top",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/ATQQ/sugar-blog.git"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/ATQQ/sugar-blog/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"vitepress",
|
|
17
|
+
"theme",
|
|
18
|
+
"粥里有勺糖"
|
|
19
|
+
],
|
|
6
20
|
"exports": {
|
|
7
21
|
"./node": {
|
|
8
22
|
"types": "./node.d.ts",
|
|
@@ -11,27 +25,13 @@
|
|
|
11
25
|
"./package.json": "./package.json",
|
|
12
26
|
".": "./src/index.ts"
|
|
13
27
|
},
|
|
28
|
+
"main": "src/index.ts",
|
|
14
29
|
"files": [
|
|
15
|
-
"
|
|
16
|
-
"types",
|
|
30
|
+
"node.d.ts",
|
|
17
31
|
"node.js",
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
"repository": {
|
|
21
|
-
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/ATQQ/sugar-blog.git"
|
|
23
|
-
},
|
|
24
|
-
"keywords": [
|
|
25
|
-
"vitepress",
|
|
26
|
-
"theme",
|
|
27
|
-
"粥里有勺糖"
|
|
32
|
+
"src",
|
|
33
|
+
"types"
|
|
28
34
|
],
|
|
29
|
-
"author": "sugar",
|
|
30
|
-
"license": "MIT",
|
|
31
|
-
"homepage": "https://theme.sugarat.top",
|
|
32
|
-
"bugs": {
|
|
33
|
-
"url": "https://github.com/ATQQ/sugar-blog/issues"
|
|
34
|
-
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@mdit-vue/shared": "^0.12.0",
|
|
37
37
|
"@mermaid-js/mermaid-mindmap": "^9.3.0",
|
|
@@ -43,19 +43,19 @@
|
|
|
43
43
|
"highlight.js": "^11.7.0",
|
|
44
44
|
"mermaid": "^10.2.4",
|
|
45
45
|
"vitepress-plugin-mermaid": "^2.0.13",
|
|
46
|
-
"vitepress-plugin-pagefind": "0.2.
|
|
46
|
+
"vitepress-plugin-pagefind": "0.2.10",
|
|
47
47
|
"vue-command-palette": "^0.1.4"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@element-plus/icons-vue": "^2.1.0",
|
|
51
51
|
"element-plus": "^2.3.4",
|
|
52
|
+
"pagefind": "1.0.3",
|
|
52
53
|
"sass": "^1.56.1",
|
|
53
54
|
"tsup": " ^6.5.0",
|
|
54
55
|
"typescript": "^4.8.2",
|
|
55
56
|
"vitepress": "1.0.0-rc.14",
|
|
56
57
|
"vitepress-plugin-tabs": "^0.2.0",
|
|
57
|
-
"vue": "^3.3.4"
|
|
58
|
-
"pagefind": "1.0.3"
|
|
58
|
+
"vue": "^3.3.4"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"dev": "npm run build:node && npm run dev:docs",
|
|
@@ -1,22 +1,6 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="global-alert" v-if="show" data-pagefind-ignore="all">
|
|
3
|
-
<el-alert
|
|
4
|
-
:title="alertProps?.title"
|
|
5
|
-
:type="alertProps?.type"
|
|
6
|
-
:show-icon="alertProps?.showIcon"
|
|
7
|
-
:center="alertProps?.center"
|
|
8
|
-
:closable="alertProps?.closable"
|
|
9
|
-
:close-text="alertProps?.closeText"
|
|
10
|
-
:description="alertProps?.description"
|
|
11
|
-
>
|
|
12
|
-
<div v-if="alertProps?.html" v-html="alertProps?.html"></div>
|
|
13
|
-
</el-alert>
|
|
14
|
-
</div>
|
|
15
|
-
</template>
|
|
16
|
-
|
|
17
1
|
<script lang="ts" setup>
|
|
18
2
|
import { ElAlert } from 'element-plus'
|
|
19
|
-
import {
|
|
3
|
+
import { onMounted, ref } from 'vue'
|
|
20
4
|
import { useBlogConfig } from '../composables/config/blog'
|
|
21
5
|
|
|
22
6
|
const { alert: alertProps } = useBlogConfig()
|
|
@@ -46,6 +30,22 @@ onMounted(() => {
|
|
|
46
30
|
})
|
|
47
31
|
</script>
|
|
48
32
|
|
|
33
|
+
<template>
|
|
34
|
+
<div v-if="show" class="global-alert" data-pagefind-ignore="all">
|
|
35
|
+
<ElAlert
|
|
36
|
+
:title="alertProps?.title"
|
|
37
|
+
:type="alertProps?.type"
|
|
38
|
+
:show-icon="alertProps?.showIcon"
|
|
39
|
+
:center="alertProps?.center"
|
|
40
|
+
:closable="alertProps?.closable"
|
|
41
|
+
:close-text="alertProps?.closeText"
|
|
42
|
+
:description="alertProps?.description"
|
|
43
|
+
>
|
|
44
|
+
<div v-if="alertProps?.html" v-html="alertProps?.html" />
|
|
45
|
+
</ElAlert>
|
|
46
|
+
</div>
|
|
47
|
+
</template>
|
|
48
|
+
|
|
49
49
|
<style lang="scss" scoped>
|
|
50
50
|
.global-alert {
|
|
51
51
|
position: fixed;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
<script setup lang="ts" name="BlogApp">
|
|
2
2
|
import Theme from 'vitepress/theme'
|
|
3
|
+
import { useBlogThemeMode } from '../composables/config/blog'
|
|
3
4
|
import BlogHomeInfo from './BlogHomeInfo.vue'
|
|
4
5
|
import BlogHomeBanner from './BlogHomeBanner.vue'
|
|
5
6
|
import BlogList from './BlogList.vue'
|
|
6
7
|
import BlogComment from './BlogComment.vue'
|
|
8
|
+
|
|
7
9
|
// import BlogSearch from './BlogSearch.vue'
|
|
8
10
|
import BlogSidebar from './BlogSidebar.vue'
|
|
9
11
|
import BlogImagePreview from './BlogImagePreview.vue'
|
|
10
12
|
import BlogArticleAnalyze from './BlogArticleAnalyze.vue'
|
|
11
13
|
import BlogAlert from './BlogAlert.vue'
|
|
12
14
|
import BlogPopover from './BlogPopover.vue'
|
|
13
|
-
import { useBlogThemeMode } from '../composables/config/blog'
|
|
14
15
|
|
|
15
16
|
const isBlogTheme = useBlogThemeMode()
|
|
16
17
|
const { Layout } = Theme
|
|
@@ -39,7 +40,7 @@ const { Layout } = Theme
|
|
|
39
40
|
<BlogSearch />
|
|
40
41
|
</template> -->
|
|
41
42
|
<!-- 自定义首页 -->
|
|
42
|
-
<template
|
|
43
|
+
<template v-if="isBlogTheme" #home-hero-before>
|
|
43
44
|
<slot name="home-hero-before" />
|
|
44
45
|
<div class="home">
|
|
45
46
|
<div class="header-banner">
|
|
@@ -49,11 +50,13 @@ const { Layout } = Theme
|
|
|
49
50
|
<div class="blog-list-wrapper">
|
|
50
51
|
<BlogList />
|
|
51
52
|
</div>
|
|
52
|
-
<div class="blog-info-wrapper"
|
|
53
|
+
<div class="blog-info-wrapper">
|
|
54
|
+
<BlogHomeInfo />
|
|
55
|
+
</div>
|
|
53
56
|
</div>
|
|
54
57
|
</div>
|
|
55
58
|
</template>
|
|
56
|
-
<template
|
|
59
|
+
<template v-if="isBlogTheme" #sidebar-nav-after>
|
|
57
60
|
<slot name="sidebar-nav-after" />
|
|
58
61
|
<BlogSidebar />
|
|
59
62
|
</template>
|
|
@@ -65,57 +68,86 @@ const { Layout } = Theme
|
|
|
65
68
|
|
|
66
69
|
<!-- 透传默认主题的其它插槽 -->
|
|
67
70
|
<!-- navbar -->
|
|
68
|
-
<template #nav-bar-title-before
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<template #nav-bar-title-after
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
<template #nav-bar-content-after
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<template #nav-screen-content-before
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
<template #nav-screen-content-after
|
|
81
|
-
|
|
82
|
-
|
|
71
|
+
<template #nav-bar-title-before>
|
|
72
|
+
<slot name="nav-bar-title-before" />
|
|
73
|
+
</template>
|
|
74
|
+
<template #nav-bar-title-after>
|
|
75
|
+
<slot name="nav-bar-title-after" />
|
|
76
|
+
</template>
|
|
77
|
+
<template #nav-bar-content-after>
|
|
78
|
+
<slot name="nav-bar-content-after" />
|
|
79
|
+
</template>
|
|
80
|
+
<template #nav-screen-content-before>
|
|
81
|
+
<slot name="nav-screen-content-before" />
|
|
82
|
+
</template>
|
|
83
|
+
<template #nav-screen-content-after>
|
|
84
|
+
<slot name="nav-screen-content-after" />
|
|
85
|
+
</template>
|
|
83
86
|
|
|
84
87
|
<!-- sidebar -->
|
|
85
|
-
<template #sidebar-nav-before
|
|
88
|
+
<template #sidebar-nav-before>
|
|
89
|
+
<slot name="sidebar-nav-before" />
|
|
90
|
+
</template>
|
|
86
91
|
|
|
87
92
|
<!-- content -->
|
|
88
|
-
<template #page-top
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<template #
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
<template #
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
<template #home-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
<template #
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
<template #
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
93
|
+
<template #page-top>
|
|
94
|
+
<slot name="page-top" />
|
|
95
|
+
</template>
|
|
96
|
+
<template #page-bottom>
|
|
97
|
+
<slot name="page-bottom" />
|
|
98
|
+
</template>
|
|
99
|
+
|
|
100
|
+
<template #not-found>
|
|
101
|
+
<slot name="not-found" />
|
|
102
|
+
</template>
|
|
103
|
+
<template #home-hero-info>
|
|
104
|
+
<slot name="home-hero-info" />
|
|
105
|
+
</template>
|
|
106
|
+
<template #home-hero-image>
|
|
107
|
+
<slot name="home-hero-image" />
|
|
108
|
+
</template>
|
|
109
|
+
<template #home-hero-after>
|
|
110
|
+
<slot name="home-hero-after" />
|
|
111
|
+
</template>
|
|
112
|
+
<template #home-features-before>
|
|
113
|
+
<slot name="home-features-before" />
|
|
114
|
+
</template>
|
|
115
|
+
<template #home-features-after>
|
|
116
|
+
<slot name="home-features-after" />
|
|
117
|
+
</template>
|
|
118
|
+
|
|
119
|
+
<template #doc-footer-before>
|
|
120
|
+
<slot name="doc-footer-before" />
|
|
121
|
+
</template>
|
|
122
|
+
|
|
123
|
+
<template #doc-top>
|
|
124
|
+
<slot name="doc-top" />
|
|
125
|
+
</template>
|
|
126
|
+
<template #doc-bottom>
|
|
127
|
+
<slot name="doc-bottom" />
|
|
128
|
+
</template>
|
|
129
|
+
|
|
130
|
+
<template #aside-top>
|
|
131
|
+
<slot name="aside-top" />
|
|
132
|
+
</template>
|
|
133
|
+
<template #aside-bottom>
|
|
134
|
+
<slot name="aside-bottom" />
|
|
135
|
+
</template>
|
|
136
|
+
<template #aside-outline-before>
|
|
137
|
+
<slot name="aside-outline-before" />
|
|
138
|
+
</template>
|
|
139
|
+
<template #aside-outline-after>
|
|
140
|
+
<slot name="aside-outline-after" />
|
|
141
|
+
</template>
|
|
142
|
+
<template #aside-ads-before>
|
|
143
|
+
<slot name="aside-ads-before" />
|
|
144
|
+
</template>
|
|
145
|
+
<template #aside-ads-after>
|
|
146
|
+
<slot name="aside-ads-after" />
|
|
147
|
+
</template>
|
|
117
148
|
</Layout>
|
|
118
149
|
</template>
|
|
150
|
+
|
|
119
151
|
<style scoped lang="scss">
|
|
120
152
|
.home {
|
|
121
153
|
margin: 0 auto;
|
|
@@ -1,47 +1,3 @@
|
|
|
1
|
-
<template>
|
|
2
|
-
<div class="doc-analyze" v-if="showAnalyze" data-pagefind-ignore="all">
|
|
3
|
-
<span>
|
|
4
|
-
<el-icon><EditPen /></el-icon>
|
|
5
|
-
字数:{{ wordCount }} 个字
|
|
6
|
-
</span>
|
|
7
|
-
<span>
|
|
8
|
-
<el-icon><AlarmClock /></el-icon>
|
|
9
|
-
预计:{{ readTime }} 分钟
|
|
10
|
-
</span>
|
|
11
|
-
</div>
|
|
12
|
-
<div class="meta-des" ref="$des" id="hack-article-des">
|
|
13
|
-
<!-- TODO:是否需要原创?转载等标签,理论上可以添加标签解决,可以参考 charles7c -->
|
|
14
|
-
<span v-if="author && !hiddenAuthor" class="author">
|
|
15
|
-
<el-icon title="本文作者"><UserFilled /></el-icon>
|
|
16
|
-
<a
|
|
17
|
-
class="link"
|
|
18
|
-
:href="currentAuthorInfo.url"
|
|
19
|
-
:title="currentAuthorInfo.des"
|
|
20
|
-
v-if="currentAuthorInfo"
|
|
21
|
-
>
|
|
22
|
-
{{ currentAuthorInfo.nickname }}
|
|
23
|
-
</a>
|
|
24
|
-
<template v-else>
|
|
25
|
-
{{ author }}
|
|
26
|
-
</template>
|
|
27
|
-
</span>
|
|
28
|
-
<span v-if="publishDate && !hiddenTime" class="publishDate">
|
|
29
|
-
<el-icon :title="timeTitle"><Clock /></el-icon>
|
|
30
|
-
{{ publishDate }}
|
|
31
|
-
</span>
|
|
32
|
-
<span v-if="tags.length" class="tags">
|
|
33
|
-
<el-icon :title="timeTitle"><CollectionTag /></el-icon>
|
|
34
|
-
<a class="link" :href="`/?tag=${tag}`" v-for="tag in tags" :key="tag"
|
|
35
|
-
>{{ tag }}
|
|
36
|
-
</a>
|
|
37
|
-
</span>
|
|
38
|
-
<!-- 封面展示 -->
|
|
39
|
-
<ClientOnly>
|
|
40
|
-
<BlogDocCover />
|
|
41
|
-
</ClientOnly>
|
|
42
|
-
</div>
|
|
43
|
-
</template>
|
|
44
|
-
|
|
45
1
|
<script lang="ts" setup>
|
|
46
2
|
// 阅读时间计算方式参考
|
|
47
3
|
// https://zhuanlan.zhihu.com/p/36375802
|
|
@@ -49,15 +5,15 @@ import { useData, useRoute } from 'vitepress'
|
|
|
49
5
|
import { computed, onMounted, ref, watch } from 'vue'
|
|
50
6
|
import { ElIcon } from 'element-plus'
|
|
51
7
|
import {
|
|
52
|
-
|
|
8
|
+
AlarmClock,
|
|
53
9
|
Clock,
|
|
10
|
+
CollectionTag,
|
|
54
11
|
EditPen,
|
|
55
|
-
|
|
56
|
-
CollectionTag
|
|
12
|
+
UserFilled
|
|
57
13
|
} from '@element-plus/icons-vue'
|
|
58
14
|
import { useBlogConfig, useCurrentArticle } from '../composables/config/blog'
|
|
59
15
|
import countWord, { formatShowDate } from '../utils/client'
|
|
60
|
-
import { Theme } from '../composables/config'
|
|
16
|
+
import type { Theme } from '../composables/config'
|
|
61
17
|
import BlogDocCover from './BlogDocCover.vue'
|
|
62
18
|
|
|
63
19
|
const { article, authorList } = useBlogConfig()
|
|
@@ -69,7 +25,7 @@ const tags = computed(() => {
|
|
|
69
25
|
[]
|
|
70
26
|
.concat(tag, tags, categories)
|
|
71
27
|
.flat()
|
|
72
|
-
.filter(
|
|
28
|
+
.filter(v => !!v)
|
|
73
29
|
)
|
|
74
30
|
]
|
|
75
31
|
})
|
|
@@ -99,20 +55,20 @@ const readTime = computed(() => {
|
|
|
99
55
|
const route = useRoute()
|
|
100
56
|
const $des = ref<HTMLDivElement>()
|
|
101
57
|
|
|
102
|
-
|
|
58
|
+
function analyze() {
|
|
103
59
|
if (!$des.value) {
|
|
104
60
|
return
|
|
105
61
|
}
|
|
106
|
-
document.querySelectorAll('.meta-des').forEach(
|
|
62
|
+
document.querySelectorAll('.meta-des').forEach(v => v.remove())
|
|
107
63
|
const docDomContainer = window.document.querySelector('#VPContent')
|
|
108
64
|
const imgs = docDomContainer?.querySelectorAll<HTMLImageElement>(
|
|
109
65
|
'.content-container .main img'
|
|
110
66
|
)
|
|
111
67
|
imageCount.value = imgs?.length || 0
|
|
112
68
|
|
|
113
|
-
const words
|
|
114
|
-
docDomContainer?.querySelector('.content-container .main')?.textContent
|
|
115
|
-
''
|
|
69
|
+
const words
|
|
70
|
+
= docDomContainer?.querySelector('.content-container .main')?.textContent
|
|
71
|
+
|| ''
|
|
116
72
|
|
|
117
73
|
wordCount.value = countWord(words)
|
|
118
74
|
docDomContainer?.querySelector('h1')?.after($des.value!)
|
|
@@ -151,11 +107,11 @@ const { theme } = useData<Theme.Config>()
|
|
|
151
107
|
const globalAuthor = computed(() => theme.value.blog?.author || '')
|
|
152
108
|
const author = computed(
|
|
153
109
|
() =>
|
|
154
|
-
(frontmatter.value.author || currentArticle.value?.meta.author)
|
|
155
|
-
globalAuthor.value
|
|
110
|
+
(frontmatter.value.author || currentArticle.value?.meta.author)
|
|
111
|
+
?? globalAuthor.value
|
|
156
112
|
)
|
|
157
113
|
const currentAuthorInfo = computed(() =>
|
|
158
|
-
authorList?.find(
|
|
114
|
+
authorList?.find(v => author.value === v.nickname)
|
|
159
115
|
)
|
|
160
116
|
const hiddenAuthor = computed(() => frontmatter.value.author === false)
|
|
161
117
|
|
|
@@ -171,6 +127,49 @@ watch(
|
|
|
171
127
|
)
|
|
172
128
|
</script>
|
|
173
129
|
|
|
130
|
+
<template>
|
|
131
|
+
<div v-if="showAnalyze" class="doc-analyze" data-pagefind-ignore="all">
|
|
132
|
+
<span>
|
|
133
|
+
<ElIcon><EditPen /></ElIcon>
|
|
134
|
+
字数:{{ wordCount }} 个字
|
|
135
|
+
</span>
|
|
136
|
+
<span>
|
|
137
|
+
<ElIcon><AlarmClock /></ElIcon>
|
|
138
|
+
预计:{{ readTime }} 分钟
|
|
139
|
+
</span>
|
|
140
|
+
</div>
|
|
141
|
+
<div id="hack-article-des" ref="$des" class="meta-des">
|
|
142
|
+
<!-- TODO:是否需要原创?转载等标签,理论上可以添加标签解决,可以参考 charles7c -->
|
|
143
|
+
<span v-if="author && !hiddenAuthor" class="author">
|
|
144
|
+
<ElIcon title="本文作者"><UserFilled /></ElIcon>
|
|
145
|
+
<a
|
|
146
|
+
v-if="currentAuthorInfo"
|
|
147
|
+
class="link"
|
|
148
|
+
:href="currentAuthorInfo.url"
|
|
149
|
+
:title="currentAuthorInfo.des"
|
|
150
|
+
>
|
|
151
|
+
{{ currentAuthorInfo.nickname }}
|
|
152
|
+
</a>
|
|
153
|
+
<template v-else>
|
|
154
|
+
{{ author }}
|
|
155
|
+
</template>
|
|
156
|
+
</span>
|
|
157
|
+
<span v-if="publishDate && !hiddenTime" class="publishDate">
|
|
158
|
+
<ElIcon :title="timeTitle"><Clock /></ElIcon>
|
|
159
|
+
{{ publishDate }}
|
|
160
|
+
</span>
|
|
161
|
+
<span v-if="tags.length" class="tags">
|
|
162
|
+
<ElIcon :title="timeTitle"><CollectionTag /></ElIcon>
|
|
163
|
+
<a v-for="tag in tags" :key="tag" class="link" :href="`/?tag=${tag}`">{{ tag }}
|
|
164
|
+
</a>
|
|
165
|
+
</span>
|
|
166
|
+
<!-- 封面展示 -->
|
|
167
|
+
<ClientOnly>
|
|
168
|
+
<BlogDocCover />
|
|
169
|
+
</ClientOnly>
|
|
170
|
+
</div>
|
|
171
|
+
</template>
|
|
172
|
+
|
|
174
173
|
<style lang="scss" scoped>
|
|
175
174
|
.doc-analyze {
|
|
176
175
|
color: var(--vp-c-text-2);
|