main.vue 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. <template>
  2. <transition name="el-fade-in">
  3. <div
  4. v-if="visible"
  5. @click.stop="handleClick"
  6. :style="{
  7. 'right': styleRight,
  8. 'bottom': styleBottom
  9. }"
  10. class="el-backtop">
  11. <slot>
  12. <el-icon name="caret-top"></el-icon>
  13. </slot>
  14. </div>
  15. </transition>
  16. </template>
  17. <script>
  18. import throttle from 'throttle-debounce/throttle';
  19. export default {
  20. name: 'ElBacktop',
  21. props: {
  22. visibilityHeight: {
  23. type: Number,
  24. default: 200
  25. },
  26. target: [String],
  27. right: {
  28. type: Number,
  29. default: 40
  30. },
  31. bottom: {
  32. type: Number,
  33. default: 40
  34. }
  35. },
  36. data() {
  37. return {
  38. el: null,
  39. container: null,
  40. visible: false
  41. };
  42. },
  43. computed: {
  44. styleBottom() {
  45. return `${this.bottom}px`;
  46. },
  47. styleRight() {
  48. return `${this.right}px`;
  49. }
  50. },
  51. mounted() {
  52. this.init();
  53. this.throttledScrollHandler = throttle(300, this.onScroll);
  54. this.container.addEventListener('scroll', this.throttledScrollHandler);
  55. },
  56. methods: {
  57. init() {
  58. this.container = document;
  59. this.el = document.documentElement;
  60. if (this.target) {
  61. this.el = document.querySelector(this.target);
  62. if (!this.el) {
  63. throw new Error(`target is not existed: ${this.target}`);
  64. }
  65. this.container = this.el;
  66. }
  67. },
  68. onScroll() {
  69. const scrollTop = this.el.scrollTop;
  70. this.visible = scrollTop >= this.visibilityHeight;
  71. },
  72. handleClick(e) {
  73. this.scrollToTop();
  74. this.$emit('click', e);
  75. },
  76. scrollToTop() {
  77. let el = this.el;
  78. let step = 0;
  79. let interval = setInterval(() => {
  80. if (el.scrollTop <= 0) {
  81. clearInterval(interval);
  82. return;
  83. }
  84. step += 10;
  85. el.scrollTop -= step;
  86. }, 20);
  87. }
  88. },
  89. beforeDestroy() {
  90. this.container.removeEventListener('scroll', this.throttledScrollHandler);
  91. }
  92. };
  93. </script>