美文网首页
vue自定义拖拽

vue自定义拖拽

作者: 菜蚴菜 | 来源:发表于2022-05-12 09:36 被阅读0次
    <template>
      <div
        ref="floatTab"
        class="float-tab"
        :style="{
          top: top + 'px',
          left: left + 'px',
        }"
        @mousedown="handleMousedown"
      >
        拖拽组件
      </div>
    </template>
    
    <script>
    // 距离窗口上下边的距离
    const fixedDirection = 50;
    // 距离右侧的固定距离
    const fixedRightDirection = 18;
    export default {
      name: 'float-tab',
      props: {},
      data() {
        return {
          /** 距离窗口头部的距离 */
          top: 0,
          /** 距离窗口右侧的距离 */
          left: 0,
          /** 组件的拖拽状态 */
          dragStatus: false,
          /** 组件的高度 */
          height: 0,
          /** 组件的宽度 */
          width: 0,
          /** 鼠标点击的时候距离内容顶部的高度 */
          mouseStartTop: 0,
          /** 鼠标点击的时候距离内容左侧的高度 */
          mouseStartLeft: 0,
          /** 窗口的高度 */
          clientHeight: 0,
          /** 窗口的宽度 */
          clientWidth: 0,
        };
      },
      created() {
        //进入页面获取窗口宽高
        this.clientHeight = document.documentElement.clientHeight;
        this.clientWidth = document.documentElement.clientWidth;
      },
      mounted() {
        // 当窗口的大小发生变化时,主要用于pc端
        window.addEventListener('resize', this.resizeFuc);
        this.$once('hook:beforeDestroy', () => {
          window.removeEventListener('mousemove', this.handleMousemove);
          window.removeEventListener('mouseup', this.handleMouseup);
          window.removeEventListener('resize', this.resizeFuc);
        });
        this.$nextTick(() => {
          // 获取拖动部分的宽高
          setTimeout(() => {
            let floatTab = this.$refs.floatTab;
            this.height = floatTab?.clientHeight:100;
            this.width = floatTab?.clientWidth:50;
            this.top = this.clientHeight - fixedDirection - this.height;
            // 开始时的距离左侧的距离为窗口宽度-右侧距离-自身宽度
            this.left = this.clientWidth - fixedRightDirection - this.width;
          });
        });
      },
      methods: {
        /** 窗口尺寸发生变化时,防止拖拽的内容被隐藏,能一直显示在页面中 */
        resizeFuc() {
          this.clientHeight = document.documentElement.clientHeight;
          this.clientWidth = document.documentElement.clientWidth;
          // 当竖直方向上窗口的尺寸发生变化,会掩盖住内容的时候、
          if (this.top + this.height + fixedDirection > this.clientHeight) {
            // 重新计算距离顶部的高度
            this.top = this.clientHeight - this.height - this.mouseStartTop;
            console.log('窗口尺寸发生变化', this.top);
          }
          // 当水平方向上窗口的尺寸发生变化,会掩盖住内容的时候、
          if (this.left + this.width + fixedRightDirection !== this.clientWidth) {
            // 重新计算距离顶部的高度
            this.left = this.clientWidth - this.width - fixedRightDirection;
            console.log('窗口尺寸发生变化', this.left);
          }
        },
        /** 释放鼠标,拖动结束*/
        handleMouseup() {
       //解除在window上的监听
        window.removeEventListener('mousemove', this.handleMousemove);
        window.removeEventListener('mouseup', this.handleMouseup);
          console.log('释放鼠标');
          this.dragStatus = false;
          // 松开鼠标内容自动贴在右侧
          this.left = this.clientWidth - this.width - fixedRightDirection;
        },
        /** 鼠标拖动,更改组件内容位置 */
        handleMousemove(e) {
          let clientY = e.clientY;
          let clientX = e.clientX;
          // 计算距离顶部的高度
          if (
            this.dragStatus &&
            clientY + this.height + fixedDirection < this.clientHeight &&
            clientY - this.mouseStartTop > fixedDirection
          ) {
            // 判断当前的位置
            this.top = clientY - this.mouseStartTop;
          }
          // 计算距离左侧的距离
          if (
            this.dragStatus &&
            clientX - this.mouseStartLeft > 0 &&
            this.clientWidth - clientX + this.mouseStartLeft >
              this.width + fixedRightDirection
          ) {
            this.left = clientX - this.mouseStartLeft;
          }
        },
        /** 按下鼠标开始拖动 */
       //注意在使用的时候再往window上绑定鼠标事件,这样减少性能消耗
        handleMousedown(e) {
          // dom中mouseup脱离元素后无法触发,所以要把 mouseup 事件挂载到全局或者 document 上即可
          window.addEventListener('mousemove', this.handleMousemove);
          window.addEventListener('mouseup', this.handleMouseup);
          console.log('按下鼠标', e.clientY, this.top);
          this.dragStatus = true;
          this.mouseStartTop = e.clientY - this.top;
          this.mouseStartLeft = e.clientX - this.left;
        },
      },
    };
    </script>
    
    <style lang="less" scoped>
    .float-tab {
      position: fixed;
      width: 50px;
      height: 100px;
      background: red;
    }
    </style>
    
    

    相关文章

      网友评论

          本文标题:vue自定义拖拽

          本文链接:https://www.haomeiwen.com/subject/rkjsurtx.html