Vue 封装 backtop 组件

组件属性

属性名类型属性值描述默认值
targetString“.className” | “#IDName”置顶目标body
visibilityHeightNumber滚动多少高度显示200
rightNumber距离浏览器右边距离50
bottomNumber距离浏览器下边距离100
事件名描述返回值
click点击时触发event,target(触发目标)
backtop到达目标时触发event,target(触发目标)

代码如下:

<template>
  <div
    v-show="isShowBackTop"
    class="vp-backtop"
    @click="backtopHandle"
    :style="{ right: `${right}px`, bottom: `${bottom}px` }"
  >
    <slot>Up</slot>
  </div>
</template>

<script>
export default {
  name: "VpBacktop",
  props: {
    target: [String],
    visibilityHeight: {
      type: Number,
      default: 200,
    },
    right: {
      type: Number,
      default: 50,
    },
    bottom: {
      type: Number,
      default: 100,
    },
  },
  data() {
    return {
      controllNum: 10,
      intervalDelay: 1,
      timer: null,
      isShowBackTop: false,
    };
  },
  created() {},
  mounted() {
    window.addEventListener("scroll", this.debounce(this.scrollHandle, 100));
  },
  methods: {
    // 防抖
    debounce(fn, wait) {
      let timer = null;
      return function () {
        if (timer !== null) clearInterval(timer);
        timer = setTimeout(fn, wait);
      };
    },
    // 点击置顶事件
    backtopHandle(e) {
      this.$emit("click", e, this.target);
      clearInterval(this.timer);
      let scrollTop =
        document.documentElement.scrollTop || document.body.scrollTop;
      let target;
      if (!this.target) {
        target = document.documentElement || document.body;
      } else {
        if (/^\./.test(this.target)) {
          target = document.getElementsByClassName(this.target.substring(1))[0];
        } else if (/^#/.test(this.target)) {
          target = document.getElementById(this.target.substring(1));
        }
      }
      let _this = this;
      if (target.offsetTop < document.documentElement.scrollTop) {
        this.timer = window.setInterval(() => {
          document.documentElement.scrollTop -= this.controllNum;
          if (document.documentElement.scrollTop <= target.offsetTop) {
            _this.$emit("backtop", e, _this.target);
            window.clearInterval(_this.timer);
          }
        }, _this.intervalDelay);
      } else {
        this.timer = window.setInterval(() => {
          document.documentElement.scrollTop += this.controllNum;
          if (document.documentElement.scrollTop >= target.offsetTop) {
            _this.$emit("backtop", e, _this.target);
            window.clearInterval(_this.timer);
          }
        }, _this.intervalDelay);
      }
    },
    // 滚动事件
    scrollHandle() {
      let scrolltop = document.documentElement.scrollTop;
      if (scrolltop >= this.visibilityHeight) {
        this.isShowBackTop = true;
      } else {
        this.isShowBackTop = false;
      }
    },
  },
};
</script>
<style scoped>
.vp-backtop {
  cursor: pointer;
  position: fixed;
  z-index: 999;
  padding: 10px 10px;
  border: 1px solid cadetblue;
  border-radius: 50%;
  background-color: cadetblue;
  color: aliceblue;
}
</style>

如需要其他更多组件,请移步到本人开发的 Vue 组件库文档:Vpro_UI
如果觉得好的话,请在 Github 上点个 star ,非常感谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值