目录
- 1.封装
- 2.调用
- 3.效果
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"><pathd="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 = falseconst handleScroll = () => {//监听页面滚动事件// 当前页面的滚动距离大于props.visibilityHeight:400时就visible设置为true,组件显示visible.value = window.pageYOffset > visibilityHeight.value
}const backToTop = () => {//返回顶部的动画效果if (isMoving) return//如果为true,说明正在执行滚动动画,因此直接返回,不执行后续操作。const start = window.pageYOffset//动画的起始位置let i = 0//初始化计数器isMoving = true//开始执行滚动动画interval = setInterval(() => {//设置一个定时器,每16.7毫秒执行一次回调函数//使用 easeInOutQuad 二次缓动函数计算下一个要滚动位置 nextconst next = Math.floor(easeInOutQuad(10 * i, start, -start, 500))if (next <= backPosition.value) {//滚动到目标位置顶部了window.scrollTo(0, backPosition.value)clearInterval(interval)//清除定时器isMoving = false//动画结束} else {//没滚到目标位置,继续往下一个next位置滚动window.scrollTo(0, next)}i++}, 16.7)
}const easeInOutQuad = (t, b, c, d) => {//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.效果
- 滚动超过400出现回到顶部按钮,点击按钮回到顶部