子组件:
<template>
<div style="scroll-behavior: smooth;">
// scroll-behavior: smooth : 平滑滚动 一定要写 不然锚点很生硬
// 但如果是用饿了么那样用js实现,就不需要这个样式的帮助
<div v-show="iftop" class="totop" @click="toTop">
<i class="el-icon-caret-top"></i>
</div>
</div>
</template>
<script>
export default {
name: 'totop',
props: { iftop: { type: Boolean } },
mounted() { //监听scroll方法
window.addEventListener('scroll', this.handleScroll)
},
beforeDestroy() { //及时释放
window.removeEventListener('scroll', this.handleScroll)
},
methods: {
handleScroll() {
let iftopChild = window.pageYOffset > 400 ? true : false
this.$emit('handleScroll', iftopChild)
},
toTop() {
window.scrollTo(0, 0)
}
}
}
</script>
父组件:
<template>
...
<Totop :iftop="iftop" @handleScroll="handleScroll"/>
...
</template>
<script>
export default {
data() {
return {
iftop: false
}
},
methods: {
handleScroll(iftop) {
this.iftop = iftop
},
}
}
</script>
element源码:
<template>
<transition name="el-fade-in">
<div
v-if="visible"
@click.stop="handleClick"
:style="{
'right': styleRight,
'bottom': styleBottom
}"
class="el-backtop">
<slot>
<el-icon name="caret-top"></el-icon>
</slot>
</div>
</transition>
</template>
<script>
import throttle from 'throttle-debounce/throttle';
export default {
name: 'ElBacktop',
props: {
visibilityHeight: {
type: Number,
default: 200
},
target: [String],
right: {
type: Number,
default: 40
},
bottom: {
type: Number,
default: 40
}
},
data() {
return {
el: null,
container: null,
visible: false
};
},
computed: {
styleBottom() {
return `${this.bottom}px`;
},
styleRight() {
return `${this.right}px`;
}
},
mounted() {
this.init();
this.throttledScrollHandler = throttle(300, this.onScroll);
this.container.addEventListener('scroll', this.throttledScrollHandler);
},
methods: {
init() {
this.container = document;
this.el = document.documentElement;
if (this.target) {
this.el = document.querySelector(this.target);
if (!this.el) {
throw new Error(`target is not existed: ${this.target}`);
}
this.container = this.el;
}
},
onScroll() {
const scrollTop = this.el.scrollTop;
this.visible = scrollTop >= this.visibilityHeight;
},
handleClick(e) {
this.scrollToTop();
this.$emit('click', e);
},
scrollToTop() {
let el = this.el;
let step = 0;
let interval = setInterval(() => {
if (el.scrollTop <= 0) {
clearInterval(interval);
return;
}
step += 10;
el.scrollTop -= step;
}, 20);
}
},
beforeDestroy() {
this.container.removeEventListener('scroll', this.throttledScrollHandler);
}
};
</script>
原组件的使用参考