Skip to content
0

配置首页小箭头效果

配置首页小箭头效果

背景

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

image-20250926072534130

效果

image-20250926073103150

配置

(1)创建docs\.vitepress\theme\components\BannerImgArrow.vue文件

vue
<script setup lang="ts" name="BannerImgArrow">
import { TkIcon } from "vitepress-theme-teek";
import arrowSvg from "../svg/arrow";
import { useData } from "vitepress";
import { ref } from "vue";

const { theme } = useData();

const namespace = "banner";

const handleClickArrow = () => {
  // 获取窗口高度
  const windowH = document.getElementsByClassName("tk-banner")[0].clientHeight;
  window.scrollTo({
    top: windowH - 20,
    behavior: "smooth",
  });
};

const isMobile = ref(false);

// 移动端不显示箭头,则打开下面注释,并引入 useWindowSize:import { useWindowSize } from "vitepress-theme-teek";
// useWindowSize(width => {
//   // if (width <= 719) isMobile.value = true;
//   // else isMobile.value = false;
// });
</script>

<template>
  <div v-if="!isMobile" :class="`${namespace}-arrow tk-wallpaper-outside`">
    <TkIcon
      :icon="arrowSvg"
      size="40px"
      color="#ffffff"
      :class="`${namespace}-arrow__icon`"
      @click="handleClickArrow"
    />
  </div>
</template>

<style lang="scss" scoped>
$namespace: banner;

.#{$namespace}-arrow {
  position: absolute;
  bottom: 120px;
  left: 50%;
  transform: translateX(-50%);

  &__icon {
    cursor: pointer;
    animation: bounce-in 3s 2s infinite;
  }
}

@keyframes bounce-in {
  0% {
    transform: translateY(0);
  }

  50% {
    transform: translateY(20px);
  }

  100% {
    transform: translateY(0);
  }
}
</style>

(2)创建docs\.vitepress\theme\svg\arrow.ts文件 (这里直接创建 svg目录/arrow.ts文件)

ts
<script setup lang="ts" name="TeekLayoutProvider">
import type { TeekConfig } from "vitepress-theme-teek";
import Teek, { teekConfigContext, clockIcon } from "vitepress-theme-teek";
import { useData } from "vitepress";
import { watch, nextTick, ref, provide } from "vue";

import BannerImgArrow from "./BannerImgArrow.vue"; //导入横幅图片箭头组件


// 默认文档风
// import { teekDocConfig } from "../config/teekConfig";

// 默认博客风
import { teekBlogCardConfig } from "../config/teekConfig";

import { useRibbon } from "../composables/useRibbon";
import { useRuntime } from "../composables/useRuntime";
import ConfigSwitch from "./ConfigSwitch.vue";
import ContributeChart from "./ContributeChart.vue";
import NotFound from "./404.vue";

const ns = "layout-provider";
const { frontmatter } = useData();

// 默认文档风
// const currentStyle = ref("doc");
// const teekConfig = ref(teekDocConfig);

// 默认博客风
const currentStyle = ref("blog-card");
const teekConfig = ref(teekBlogCardConfig);

provide(teekConfigContext, teekConfig);

// 彩带背景
const { start: startRibbon, stop: stopRibbon } = useRibbon({ immediate: false, clickReRender: true });
// 页脚运行时间
const { start: startRuntime, stop: stopRuntime } = useRuntime("2021-10-19 00:00:00", {
  prefix: `<span style="width: 16px; display: inline-block; vertical-align: -3px; margin-right: 3px;">${clockIcon}</span>小破站已运行 `,
});

const watchRuntimeAndRibbon = async (layout: string, style: string) => {
  const isHome = layout === "home";
  const isDoc = [undefined, "doc"].includes(layout);
  const isBlog = style.startsWith("blog");

  // 博客类风格的首页显示运行时间
  await nextTick();
  if (isHome && isBlog) startRuntime();
  else stopRuntime();

  // 博客类风格的首页显示彩带 & 设置了 pageStyle 的文章页显示彩带
  if ((isHome && isBlog && style !== "blog-body") || (isDoc && teekConfig.value.pageStyle)) startRibbon();
  else stopRibbon();
};

watch(frontmatter, newVal => setTimeout(() => watchRuntimeAndRibbon(newVal.layout, currentStyle.value), 700), {
  immediate: true,
  flush: "post",
});

const handleConfigSwitch = (config: TeekConfig, style: string) => {
  teekConfig.value = config;

  setTimeout(() => watchRuntimeAndRibbon(frontmatter.value.layout, style), 700);
};
</script>

<template>
  <Teek.Layout>
    <template #teek-theme-enhance-bottom>
      <div :class="[ns, 'flx-align-center']">
        <ConfigSwitch v-model="currentStyle" @switch="handleConfigSwitch" />
      </div>
    </template>

    <template #nav-screen-content-after>
      <ConfigSwitch v-model="currentStyle" @switch="handleConfigSwitch" />
    </template>

    <template #teek-archives-top-before>
      <ContributeChart />
    </template>

    <template #not-found>
      <NotFound />
    </template>

    <template #teek-home-banner-feature-after>
      <!-- 横幅图片箭头组件 -->
      <BannerImgArrow />
    </template>

  </Teek.Layout>
</template>

<style lang="scss">
.tk-my.is-circle-bg {
  .tk-my__avatar.circle-rotate {
    margin-top: 200px;

    .tk-avatar:not(.avatar-sticker) {
      border: 5px solid var(--vp-c-bg-elv);
    }
  }
}
</style>

(3)编辑docs\.vitepress\theme\components\TeekLayoutProvider.vue文件

vue
import BannerImgArrow from "./BannerImgArrow.vue"; //导入横幅图片箭头组件

    <template #teek-home-banner-feature-after>
      <!-- 横幅图片箭头组件 -->
      <BannerImgArrow />
    </template>

image-20250926073432561

image-20250926073448160

(4)运行项目验证。

效果见上文。

结束。

最近更新