1.封装
<template>
<transition :name="transitionName">
<div v-show="visible" class="back-to-ceiling" @click="backToTop">
<svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg"
class="Icon Icon--backToTopArrow" aria-hidden="true" style="height:16px;width:16px">
<path
d="M12.036 15.59a1 1 0 0 1-.997.995H5.032a.996.996 0 0 1-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" />
</svg>
</div>
</transition>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
const backPosition = ref(0);
const transitionName = ref('fade');
const visibilityHeight = ref(400);
const visible = ref(false)
let interval = null
let isMoving = false
const handleScroll = () => {
visible.value = window.pageYOffset > visibilityHeight.value
}
const backToTop = () => {
if (isMoving) return
const start = window.pageYOffset
let i = 0
isMoving = true
interval = setInterval(() => {
const next = Math.floor(easeInOutQuad(10 * i, start, -start, 500))
if (next <= backPosition.value) {
window.scrollTo(0, backPosition.value)
clearInterval(interval)
isMoving = false
} else {
window.scrollTo(0, next)
}
i++
}, 16.7)
}
const easeInOutQuad = (t, b, c, d) => {
if ((t /= d / 2) < 1) return (c / 2) * t * t + b
return (-c / 2) * (--t * (t - 2) - 1) + b
}
onMounted(() => {
window.addEventListener('scroll', handleScroll)
})
onBeforeUnmount(() => {
window.removeEventListener('scroll', handleScroll)
if (interval) {
clearInterval(interval)
}
})
</script>
<style scoped>
.back-to-ceiling {
position: fixed;
display: inline-block;
text-align: center;
cursor: pointer;
right: 50px;
bottom: 50px;
width: 40px;
height: 40px;
border-radius: 4px;
line-height: 45px;
background: #e7eaf1;
}
.back-to-ceiling:hover {
background: #d5dbe7;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.back-to-ceiling .Icon {
fill: #9aaabf;
background: none;
}
</style>
2.调用
<template>
<el-tooltip placement="top" content="tooltip">
<back-to-top class="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade" />
</el-tooltip>
</template>
<script setup lang="ts">
import BackToTop from '@/components/BackToTop/index.vue'
</script>
<style scoped>
.myBackToTopStyle {
right: '50px';
bottom: '50px';
width: '40px';
height: '40px';
border-radius: '4px';
line-height: '45px';
background: '#e7eaf1';
}
</style>
3.效果

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人