vue实现原生吸顶
Vue 实现原生吸顶效果
吸顶效果是指当页面滚动时,某个元素固定在顶部不随滚动条移动。以下是几种实现方式:
使用 CSS 的 position: sticky
CSS 的 position: sticky 是最简单的实现方式,无需 JavaScript 代码:
<template>
<div class="sticky-header">
<!-- 吸顶内容 -->
</div>
</template>
<style>
.sticky-header {
position: sticky;
top: 0;
z-index: 100;
background: white;
}
</style>
position: sticky 需要指定 top 值,表示距离顶部多少像素时开始固定。兼容性较好,但在某些旧浏览器中可能需要前缀。

使用 JavaScript 监听滚动事件
如果需要更复杂的逻辑(如动态计算位置),可以通过监听滚动事件实现:
<template>
<div ref="stickyHeader" :class="{ 'fixed-header': isSticky }">
<!-- 吸顶内容 -->
</div>
</template>
<script>
export default {
data() {
return {
isSticky: false,
stickyOffset: 0
};
},
mounted() {
this.stickyOffset = this.$refs.stickyHeader.offsetTop;
window.addEventListener('scroll', this.handleScroll);
},
beforeDestroy() {
window.removeEventListener('scroll', this.handleScroll);
},
methods: {
handleScroll() {
this.isSticky = window.pageYOffset > this.stickyOffset;
}
}
};
</script>
<style>
.fixed-header {
position: fixed;
top: 0;
width: 100%;
z-index: 100;
background: white;
}
</style>
这种方式通过监听 scroll 事件动态添加或移除 fixed-header 类名实现吸顶。

结合 Intersection Observer API
现代浏览器支持 IntersectionObserver,性能优于滚动监听:
<template>
<div>
<div ref="sentinel"></div>
<div ref="stickyHeader" :class="{ 'fixed-header': isSticky }">
<!-- 吸顶内容 -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
isSticky: false
};
},
mounted() {
const observer = new IntersectionObserver(
([entry]) => {
this.isSticky = !entry.isIntersecting;
},
{ threshold: [1] }
);
observer.observe(this.$refs.sentinel);
}
};
</script>
IntersectionObserver 监听一个哨兵元素(sentinel),当其离开视口时触发吸顶效果。
注意事项
- 吸顶元素的
z-index应合理设置以避免被其他元素遮挡。 - 固定定位可能导致下方内容突然上跳,可通过占位元素或动态计算高度解决。
- 移动端可能需要考虑
position: sticky的兼容性问题。






