惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
GbyAI
GbyAI
S
SegmentFault 最新的问题
量子位
爱范儿
爱范儿
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MyScale Blog
MyScale Blog
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
aimingoo的专栏
aimingoo的专栏
V
Visual Studio Blog
U
Unit 42
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
The Cloudflare Blog
Stack Overflow Blog
Stack Overflow Blog
博客园 - 聂微东
J
Java Code Geeks
The GitHub Blog
The GitHub Blog
Y
Y Combinator Blog
IT之家
IT之家
Martin Fowler
Martin Fowler
宝玉的分享
宝玉的分享
雷峰网
雷峰网

Hyde Blog

Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog Hyde Blog
Hyde Blog
Hyde · 2025-12-10 · via Hyde Blog

vue

<template>
  <div
    ref="progressBar"
    class="progress-bar"
    :style="{ width: progress + '%' }"
  ></div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from "vue";

const progressBar = ref(null);
const progress = ref(0);

let ticking = false;

const handleScroll = () => {
  if (!ticking) {
    requestAnimationFrame(() => {
      const { documentElement, body } = document;
      // 批量读取
      const measurements = {
        scrollHeight: documentElement.scrollHeight,
        clientHeight: documentElement.clientHeight,
        scrollTop: documentElement.scrollTop || body.scrollTop,
      };
      const totalHeight = measurements.scrollHeight - measurements.clientHeight;
      // 批量更新
      progress.value = (measurements.scrollTop / totalHeight) * 100;
      ticking = false;
    });
    ticking = true;
  }
};

onMounted(() => {
  window.addEventListener("scroll", handleScroll);
});

onUnmounted(() => {
  window.removeEventListener("scroll", handleScroll);
});
</script>

<style scoped>
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  height: 2px;
  background: linear-gradient(
    107deg,
    rgb(255, 182, 133) -30.6%,
    rgb(255, 111, 29) -1.11%,
    rgb(252, 181, 232) 39.14%,
    rgb(135, 148, 255) 73.35%,
    rgb(60, 112, 255) 97.07%,
    rgb(60, 112, 255) 118.97%
  );
  z-index: 9999;
}
</style>

vue

<script setup lang="ts" name="TeekLayoutProvider">
// @ts-ignore
import ScrollProgressBar from "./ScrollProgressBar.vue"; //导入顶部滚动条组件
</script>

<template>
  <Teek.Layout>
    <template #layout-top>
      <!-- 顶部滚动条组件 -->
      <ScrollProgressBar />
    </template>
    其他组件...
  </Teek.Layout>
</template>