Skip to content

Commit 29275ab

Browse files
committed
feat: 🚀 post 部分配置移到 article,article 新增在文章页运行自定义文章信息到指定 DOM 位置
1 parent 2ee27d8 commit 29275ab

File tree

5 files changed

+94
-31
lines changed

5 files changed

+94
-31
lines changed

vitepress-theme-teeker/src/components/ArticleAnalyze.vue

+30-9
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
import { useRoute, useData } from "vitepress";
33
import { useNamespace, useBuSunZi } from "../hooks";
44
import { ElBreadcrumb, ElBreadcrumbItem, ElIcon } from "element-plus";
5-
import { computed, unref } from "vue";
5+
import { computed, nextTick, onMounted, ref, unref } from "vue";
66
import { House, Reading, Clock, View } from "@element-plus/icons-vue";
77
import { useUnrefData } from "../configProvider";
88
import { FileInfo } from "vitepress-plugin-doc-analysis";
99
import PostBaseInfo from "./PostBaseInfo.vue";
10-
import { Breadcrumb, DocAnalysis, Post } from "../config/types";
10+
import { Article, Breadcrumb, DocAnalysis } from "../config/types";
1111
import { TkContentData } from "../post/types";
1212
1313
const ns = useNamespace("articleAnalyze");
@@ -74,17 +74,38 @@ const pageViewInfo = computed(() => {
7474
return pageViewInfo;
7575
});
7676
77-
const { showBaseInfo = true }: Post = { ...theme.post, ...frontmatter.post };
77+
// 文章信息配置项
78+
const { showInfo = true, teleport = {} }: Article = { ...theme.article, ...frontmatter.article };
7879
7980
// 是否展示作者、日期、分类、标签等信息
80-
const isShowBaseInfo = computed(() => {
81-
const arr = [showBaseInfo].flat();
81+
const isShowInfo = computed(() => {
82+
const arr = [showInfo].flat();
8283
if (arr.includes(true) || arr.includes("article")) return true;
8384
return false;
8485
});
8586
8687
// 通过不蒜子获取页面访问量
8788
const { pagePv, isGet } = useBuSunZi(pageIteration);
89+
90+
const baseInfoRef = ref<HTMLDivElement>();
91+
const teleportInfo = () => {
92+
const { selector, position = "after", className = "teleport" } = teleport;
93+
// 没有指定选择器,则不进行传送
94+
if (!selector) return;
95+
96+
const docDomContainer = window.document.querySelector("#VPContent");
97+
let h1Dom = docDomContainer?.querySelector(selector);
98+
99+
// 传送前先尝试删除传送位置的自己,避免重新传送渲染
100+
h1Dom?.parentElement?.querySelectorAll(`.${ns.e("wrapper")}`).forEach(v => v.remove());
101+
102+
unref(baseInfoRef).classList.add(className);
103+
h1Dom?.[position]?.(unref(baseInfoRef));
104+
};
105+
106+
onMounted(() => {
107+
nextTick(() => teleportInfo());
108+
});
88109
</script>
89110

90111
<template>
@@ -107,22 +128,22 @@ const { pagePv, isGet } = useBuSunZi(pageIteration);
107128
</el-breadcrumb-item>
108129
</el-breadcrumb>
109130

110-
<div v-if="isShowBaseInfo" :class="`${ns.e('wrapper')} flx-center`">
131+
<div v-if="isShowInfo" ref="baseInfoRef" :class="`${ns.e('wrapper')} flx-align-center`">
111132
<PostBaseInfo :post scope="article" />
112133

113134
<div v-if="wordCount" class="flx-center">
114135
<el-icon><Reading /></el-icon>
115-
<a title="文章字数">{{ pageViewInfo.wordCount }}</a>
136+
<a title="文章字数" class="hover-color">{{ pageViewInfo.wordCount }}</a>
116137
</div>
117138

118139
<div v-if="readingTime" class="flx-center">
119140
<el-icon><Clock /></el-icon>
120-
<a title="预计阅读时长">{{ pageViewInfo.readingTime }}</a>
141+
<a title="预计阅读时长" class="hover-color">{{ pageViewInfo.readingTime }}</a>
121142
</div>
122143

123144
<div v-if="pageView" class="flx-center">
124145
<el-icon><View /></el-icon>
125-
<a title="浏览量">{{ isGet ? pagePv : "Get..." }}</a>
146+
<a title="浏览量" class="hover-color">{{ isGet ? pagePv : "Get..." }}</a>
126147
</div>
127148
</div>
128149
</div>

vitepress-theme-teeker/src/components/HomePostItem.vue

+6-6
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { TkContentData } from "../post/types";
66
import { createImageViewer } from "./ImageViewer";
77
import { useUnrefData } from "../configProvider";
88
import PostBaseInfo from "./PostBaseInfo.vue";
9-
import { Post } from "../config/types";
9+
import { Article, Post } from "../config/types";
1010
1111
const ns = useNamespace("postItem");
1212
@@ -20,9 +20,9 @@ const {
2020
moreLabel = "阅读全文 >",
2121
coverImgMode = "default",
2222
showCapture = false,
23-
showBaseInfo = true,
2423
imageViewer = {},
2524
}: Post = { ...theme.post, ...frontmatter.tk?.post };
25+
const { showInfo = true }: Article = { ...theme.article, ...frontmatter.tk?.article };
2626
2727
const excerpt = post.frontmatter.description || post.excerpt || (showCapture && post.capture);
2828
@@ -58,9 +58,9 @@ const coverImgMap = computed(() => {
5858
});
5959
6060
// 是否展示作者、日期、分类、标签等信息
61-
const isShowBaseInfo = computed(() => {
62-
const arr = [showBaseInfo].flat();
63-
if (arr.includes(true) || arr.includes("home")) return true;
61+
const isShowInfo = computed(() => {
62+
const arr = [showInfo].flat();
63+
if (arr.includes(true) || arr.includes("post")) return true;
6464
return false;
6565
});
6666
</script>
@@ -84,7 +84,7 @@ const isShowBaseInfo = computed(() => {
8484

8585
<!-- 文章信息 -->
8686
<div :class="ns.e('__info__left__footer')">
87-
<PostBaseInfo v-if="isShowBaseInfo" :post scope="home" split />
87+
<PostBaseInfo v-if="isShowInfo" :post scope="home" split />
8888
</div>
8989

9090
<!-- 摘要 bottom -->

vitepress-theme-teeker/src/components/PostBaseInfo.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { formatDate, isFunction } from "../helper";
77
import { TkContentData } from "../post/types";
88
import { useNamespace } from "../hooks";
99
import { useRoute } from "vitepress";
10-
import { Post } from "../config/types";
10+
import { Article, Post } from "../config/types";
1111
1212
const ns = useNamespace("postBaseInfo");
1313
@@ -28,7 +28,7 @@ const {
2828
showDate = true,
2929
showCategory = false,
3030
showTag = false,
31-
}: Post = { ...theme.post, ...frontmatter.post, ...frontmatter.tk?.post };
31+
}: Article = { ...theme.article, ...frontmatter.article, ...frontmatter.tk?.article };
3232
3333
const posts = usePosts();
3434
const route = useRoute();

vitepress-theme-teeker/src/config/types.ts

+41-13
Original file line numberDiff line numberDiff line change
@@ -98,37 +98,41 @@ export interface TkThemeConfig {
9898
*/
9999
bodyBgImg?: BodyBgImg;
100100
/**
101-
* 首页 Banner 配置,里面的属性全部支持在 frontmatter 配置 tk.banner.[key]
101+
* 首页 Banner 配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.banner.[key]
102102
*/
103103
banner?: Banner;
104104
/**
105105
* 博主信息 (显示在首页侧边栏)
106106
*/
107107
blogger?: Blogger;
108108
/**
109-
* 精选文章卡片配置,里面的属性全部支持在 frontmatter 配置 tk.topArticle.[key]
109+
* 精选文章卡片配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.topArticle.[key]
110110
*/
111111
topArticle?: TopArticle;
112112
/**
113-
* 分类卡片配置,里面的属性全部支持在 frontmatter 配置 tk.category.[key]
113+
* 分类卡片配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.category.[key]
114114
*/
115115
category?: Category;
116116
/**
117-
* 标签卡片配置,里面的属性全部支持在 frontmatter 配置 tk.tag.[key]
117+
* 标签卡片配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.tag.[key]
118118
*/
119119
tag?: Tag;
120120
/**
121-
* 友情链接卡片配置,里面的属性全部支持在 frontmatter 配置 tk.friendLink.[key]
121+
* 友情链接卡片配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.friendLink.[key]
122122
*/
123123
friendLink?: FriendLink;
124124
/**
125-
* 站点信息卡片配置,里面的属性全部支持在 frontmatter 配置 tk.docAnalysis.[key]
125+
* 站点信息卡片配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.docAnalysis.[key]
126126
*/
127127
docAnalysis?: DocAnalysis;
128128
/**
129-
* 文章列表配置,支持在 frontmatter 配置,如果是首页 index.md,则是 tk.post.[key],如果是非首页 index.md,则是 post.[key]
129+
* 文章列表配置,里面的属性全部支持在 frontmatter 配置,格式为 tk.post.[key]
130130
*/
131131
post?: Post;
132+
/**
133+
* 文章信息配置,支持在 frontmatter 配置,如果在首页(index.md),格式为 tk.article.[key],如果在文章页(非 index.md),格式为 article.[key]
134+
*/
135+
article?: Article;
132136
/**
133137
* 面包屑配置,里面的属性全部支持在 frontmatter 配置 breadcrumb.[key]
134138
*/
@@ -713,7 +717,14 @@ export interface Post {
713717
*/
714718
showCapture?: boolean;
715719
/**
716-
* 作者、日期、分类、标签、字数、阅读时长、浏览量等基本信息的图标是否显示
720+
* 首页的图片查看器配置,完全是 ElImageViewer 的 props
721+
*/
722+
imageViewer?: Partial<ImageViewerProps>;
723+
}
724+
725+
export interface Article {
726+
/**
727+
* 作者、日期、分类、标签、字数、阅读时长、浏览量等文章信息的图标是否显示
717728
*
718729
* @default true
719730
*/
@@ -725,12 +736,12 @@ export interface Post {
725736
*/
726737
dateFormat?: "yyyy-MM-dd" | "yyyy-MM-dd hh:mm:ss" | ((date: string) => string);
727738
/**
728-
* 是否展示作者、日期、分类、标签、字数、阅读时长、浏览量等基本信息,分别作用于首页和文章页
729-
* 如果 showBaseInfo 为数组,则控制在哪里显示,如 ["home"] 只在首页显示基本信息;如果为 boolean 值,则控制基本信息是否展示,如 false 则在首页和文章页都不显示基本信息
739+
* 是否展示作者、日期、分类、标签、字数、阅读时长、浏览量等文章信息,分别作用于首页和文章页
740+
* 如果 showInfo 为数组,则控制在哪里显示,如 ["post"] 只在首页的 Post 列表显示基本信息;如果为 boolean 值,则控制基本信息是否展示,如 false 则在首页和文章页都不显示基本信息
730741
*
731742
* @default true
732743
*/
733-
showBaseInfo?: boolean | ("home" | "article")[];
744+
showInfo?: boolean | ("post" | "article")[];
734745
/**
735746
* 文章页是否展示作者
736747
*
@@ -756,9 +767,26 @@ export interface Post {
756767
*/
757768
showTag?: boolean;
758769
/**
759-
* 首页的图片查看器配置,完全是 ElImageViewer 的 props
770+
* 指定文章信息的传送位置,仅限在文章页生效,默认在文章页顶部
760771
*/
761-
imageViewer?: Partial<ImageViewerProps>;
772+
teleport?: {
773+
/**
774+
* 指定需要传送的元素选择器
775+
*/
776+
selector?: string;
777+
/**
778+
* 指定传送到元素的位置,before 在元素前,after 在元素后
779+
*
780+
* @default 'after'
781+
*/
782+
position?: "before" | "after";
783+
/**
784+
* 指定一个 class 名,如果传送的位置和其他元素太接近,可以利用 class 来修改 margin
785+
*
786+
* @default teleport
787+
*/
788+
className?: string;
789+
};
762790
}
763791

764792
export interface Breadcrumb {

vitepress-theme-teeker/src/styles/components/articleAnalyze.scss

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
@include b(articleAnalyze) {
55
flex-wrap: wrap;
6-
color: var(--vp-c-text-2);
76
font-size: 14px;
87
margin-bottom: 24px;
98
gap: getCssVar("gap1");
@@ -26,12 +25,27 @@
2625
}
2726

2827
@include e(wrapper) {
28+
flex-wrap: wrap;
29+
30+
&.teleport {
31+
margin-top: 10px;
32+
margin-bottom: 10px;
33+
}
34+
2935
& > div:not(:last-child) {
3036
margin-right: 14px;
3137
}
3238

39+
a {
40+
font-weight: 400;
41+
color: var(--vp-c-text-2);
42+
text-decoration: none;
43+
font-size: 14px;
44+
}
45+
3346
i {
3447
margin-right: 3px;
48+
color: var(--vp-c-text-2);
3549
}
3650
}
3751
}

0 commit comments

Comments
 (0)