跳到主要内容

配置首页小箭头效果

最后更新于:

配置首页小箭头效果

背景

默认是没箭头的,这里给它配上一个箭头哦。

image-20250926072534130

效果

image-20250926073103150

配置

(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>

image-20250926073432561

image-20250926073448160

(4)运行项目验证。

效果见上文。

结束。

最新文章

文档导航