快捷菜单
常用功能一站直达
更多功能请点顶栏「快捷菜单」
默认是没箭头的,这里给它配上一个箭头哦。


(1)创建docs\.vitepress\theme\components\BannerImgArrow.vue文件
1<script setup lang="ts" name="BannerImgArrow">
2import { TkIcon } from "vitepress-theme-teek";
3import arrowSvg from "../svg/arrow";
4import { useData } from "vitepress";
5import { ref } from "vue";
6
7const { theme } = useData();
8
9const namespace = "banner";
10
11const handleClickArrow = () => {
12 // 获取窗口高度
13 const windowH = document.getElementsByClassName("tk-banner")[0].clientHeight;
14 window.scrollTo({
15 top: windowH - 20,
16 behavior: "smooth",
17 });
18};
19
20const isMobile = ref(false);
21
22// 移动端不显示箭头,则打开下面注释,并引入 useWindowSize:import { useWindowSize } from "vitepress-theme-teek";
23// useWindowSize(width => {
24// // if (width <= 719) isMobile.value = true;
25// // else isMobile.value = false;
26// });
27</script>
28
29<template>
30 <div v-if="!isMobile" :class="`${namespace}-arrow tk-wallpaper-outside`">
31 <TkIcon
32 :icon="arrowSvg"
33 size="40px"
34 color="#ffffff"
35 :class="`${namespace}-arrow__icon`"
36 @click="handleClickArrow"
37 />
38 </div>
39</template>
40
41<style lang="scss" scoped>
42$namespace: banner;
43
44.#{$namespace}-arrow {
45 position: absolute;
46 bottom: 120px;
47 left: 50%;
48 transform: translateX(-50%);
49
50 &__icon {
51 cursor: pointer;
52 animation: bounce-in 3s 2s infinite;
53 }
54}
55
56@keyframes bounce-in {
57 0% {
58 transform: translateY(0);
59 }
60
61 50% {
62 transform: translateY(20px);
63 }
64
65 100% {
66 transform: translateY(0);
67 }
68}
69</style>(2)创建docs\.vitepress\theme\svg\arrow.ts文件 (这里直接创建 svg目录/arrow.ts文件)
1<script setup lang="ts" name="TeekLayoutProvider">
2import type { TeekConfig } from "vitepress-theme-teek";
3import Teek, { teekConfigContext, clockIcon } from "vitepress-theme-teek";
4import { useData } from "vitepress";
5import { watch, nextTick, ref, provide } from "vue";
6
7import BannerImgArrow from "./BannerImgArrow.vue"; //导入横幅图片箭头组件
8
9
10// 默认文档风
11// import { teekDocConfig } from "../config/teekConfig";
12
13// 默认博客风
14import { teekBlogCardConfig } from "../config/teekConfig";
15
16import { useRibbon } from "../composables/useRibbon";
17import { useRuntime } from "../composables/useRuntime";
18import ConfigSwitch from "./ConfigSwitch.vue";
19import ContributeChart from "./ContributeChart.vue";
20import NotFound from "./404.vue";
21
22const ns = "layout-provider";
23const { frontmatter } = useData();
24
25// 默认文档风
26// const currentStyle = ref("doc");
27// const teekConfig = ref(teekDocConfig);
28
29// 默认博客风
30const currentStyle = ref("blog-card");
31const teekConfig = ref(teekBlogCardConfig);
32
33provide(teekConfigContext, teekConfig);
34
35// 彩带背景
36const { start: startRibbon, stop: stopRibbon } = useRibbon({ immediate: false, clickReRender: true });
37// 页脚运行时间
38const { start: startRuntime, stop: stopRuntime } = useRuntime("2021-10-19 00:00:00", {
39 prefix: `<span style="width: 16px; display: inline-block; vertical-align: -3px; margin-right: 3px;">${clockIcon}</span>小破站已运行 `,
40});
41
42const watchRuntimeAndRibbon = async (layout: string, style: string) => {
43 const isHome = layout === "home";
44 const isDoc = [undefined, "doc"].includes(layout);
45 const isBlog = style.startsWith("blog");
46
47 // 博客类风格的首页显示运行时间
48 await nextTick();
49 if (isHome && isBlog) startRuntime();
50 else stopRuntime();
51
52 // 博客类风格的首页显示彩带 & 设置了 pageStyle 的文章页显示彩带
53 if ((isHome && isBlog && style !== "blog-body") || (isDoc && teekConfig.value.pageStyle)) startRibbon();
54 else stopRibbon();
55};
56
57watch(frontmatter, newVal => setTimeout(() => watchRuntimeAndRibbon(newVal.layout, currentStyle.value), 700), {
58 immediate: true,
59 flush: "post",
60});
61
62const handleConfigSwitch = (config: TeekConfig, style: string) => {
63 teekConfig.value = config;
64
65 setTimeout(() => watchRuntimeAndRibbon(frontmatter.value.layout, style), 700);
66};
67</script>
68
69<template>
70 <Teek.Layout>
71 <template #teek-theme-enhance-bottom>
72 <div :class="[ns, 'flx-align-center']">
73 <ConfigSwitch v-model="currentStyle" @switch="handleConfigSwitch" />
74 </div>
75 </template>
76
77 <template #nav-screen-content-after>
78 <ConfigSwitch v-model="currentStyle" @switch="handleConfigSwitch" />
79 </template>
80
81 <template #teek-archives-top-before>
82 <ContributeChart />
83 </template>
84
85 <template #not-found>
86 <NotFound />
87 </template>
88
89 <template #teek-home-banner-feature-after>
90 <!-- 横幅图片箭头组件 -->
91 <BannerImgArrow />
92 </template>
93
94 </Teek.Layout>
95</template>
96
97<style lang="scss">
98.tk-my.is-circle-bg {
99 .tk-my__avatar.circle-rotate {
100 margin-top: 200px;
101
102 .tk-avatar:not(.avatar-sticker) {
103 border: 5px solid var(--vp-c-bg-elv);
104 }
105 }
106}
107</style>(3)编辑docs\.vitepress\theme\components\TeekLayoutProvider.vue文件
1import BannerImgArrow from "./BannerImgArrow.vue"; //导入横幅图片箭头组件
2
3 <template #teek-home-banner-feature-after>
4 <!-- 横幅图片箭头组件 -->
5 <BannerImgArrow />
6 </template>

(4)运行项目验证。
效果见上文。
结束。
日历 · 精选 · 友链 · 更多
如果内容对你有帮助,欢迎请我喝杯咖啡 ☕



One的公众号
爱折腾博客的小白