vue2 拖拽组件

完整的代码, 可以复制引用

Vue 右上角拖拽的客服图标组件

<template>
  <!-- 客服图标链接 -->
  <a :href="$store.state.user.info.kefulink" class="server"
     ref="drawable"
     :style="{right: right, top: top}"
     @touchstart="touchstart"
     @touchend="touchend"
     @touchmove="mousemove"
  >
    <!-- 客服图标 -->
    <img src="../assets/img/kefu.png" class="server-icon">
  </a>
</template>
    


<script>
  export default {
    props: {
      top: 0,
      right: 0,
      isOnlyLeft: Boolean,  // 仅在左边拖动时使用
      isOnlyRight: Boolean, // 仅在右边拖动时使用
    },
    data() {
      return {
        flag: false // 标志位,用于判断是否正在进行拖动操作
      };
    },
    methods: {
      touchstart() {
        this.flag = true;
        document.getElementById('app').style = 'overflow: hidden;'; // 禁用页面滚动条
        this.$refs.drawable.style.transition = 'none'; // 取消动画,使拖拽更加流畅
      },
      touchend() {
        this.flag = false;
        this.$refs.drawable.style.transition = 'all 0.2s'; // 恢复动画
        document.getElementById('app').style = 'overflow: auto;'; // 恢复页面滚动
        let left = this.$refs.drawable.offsetLeft;
        let screenWidth = window.screen.width;
        let oWidth = this.$refs.drawable.offsetWidth;
        if (left + oWidth / 2 <= screenWidth / 2) {
          this.$refs.drawable.style.left = '0px';
        } else {
          this.$refs.drawable.style.left = screenWidth - oWidth + 'px';
        }
      },
      mousemove(e) {
        e.preventDefault(); // 阻止默认行为,避免和其他事件冲突
        if (this.flag) {
          let clientY = e.targetTouches[0].clientY; // 获取当前触摸点的位置
          let clientX = e.targetTouches[0].clientX;
          let offsetHeight = this.$refs.drawable.offsetHeight;
          let offsetWidth = this.$refs.drawable.offsetWidth;
          let top = clientY - offsetHeight / 2; // 计算元素应该移动到的位置
          let left = clientX - offsetWidth / 2;
          let screenWidth = window.screen.width;
          let screenHeight = window.screen.height;
          let maxTop = screenHeight - offsetHeight;
          let maxLeft = screenWidth - offsetWidth;
          if (top <= 0) top = 0;
          if (top > maxTop) top = maxTop;
          if (left <= 0) left = 0;
          if (left > maxLeft) left = maxLeft;
          this.$refs.drawable.style.top = top + 'px'; // 更新元素的位置
          this.$refs.drawable.style.left = left + 'px';
        }
      }
    },
  }
</script>
    
<style lang="scss">
  .server {
    position: fixed; // 固定定位
    z-index: 100;    // z轴层级
    top: 75px;
    right: 0px;
    width: 48px;
    border-radius: 50%; // 圆形边框
  }
</style>

posted on 2022-06-04 19:57  完美前端  阅读(1642)  评论(0)    收藏  举报

导航