vue封装包含区域内不可拖拽的可拖拽组件

标题比较绕口,大概意思就是封装一个可拖拽组件,但是因为组件内有文件或者表单或者其它原因而不可在这个区域内使用拖拽,所以在绑定拖拽区域方法的同时限制不可拖拽区域。

实现方式很简单  

直接看代码

drag.js

import Vue from 'vue'
export const drag = Vue.directive('drag',{
    bind: (el, binding) => {
      // console.log(el);
      // console.log(binding.value);
      //绑定默认样式
      el.style.zIndex = 9;
      // el.style.backgroundColor = "rgba(189,220,251,0.88)";
      el.style.radius = "4px";
      //如果为编辑状态
      if (binding.value || binding.value === undefined) {
        //定义该元素的 top left width height
        let x, y, w, h;
        //鼠标的起始和结束坐标
        let cx_start, cy_start, cx_end, cy_end;
        
        //判断鼠标样式
        el.onmousemove = (e) => {
          //获取鼠标当前位置
          let cx_now = e.clientX;
          let cy_now = e.clientY;
          //获取div右下角相对浏览器的位置
          let {
            top: el_top,
            left: el_left,
            width: el_width,
            height: el_height,
          } = el.getBoundingClientRect();
          let el_bottom_height = el_top + el_height;
          let el_right_width = el_left + el_width;
          //判断鼠标是否在div下边界
          let mouse_in_bottom =
            cy_now <= el_bottom_height + 5 && cy_now >= el_bottom_height - 5;
            // 添加图间区间
            // let qujian =  cy_now <= el_bottom_height - 5 && cy_now >= el_right_width - 5;

          //判断鼠标是否在div右边界
          let mouse_in_right =
            cx_now <= el_right_width + 5 && cx_now >= el_right_width - 5;
          if (mouse_in_bottom && mouse_in_right) {
            el.style.cursor = "se-resize";
          } else if (mouse_in_right) {
            el.style.cursor = "e-resize";
          } else if (mouse_in_bottom) {
            el.style.cursor = "s-resize";
          } else{
            el.style.cursor = "move";
          }
        };
        
        el.onmousedown = (e) => {
        //   console.log(e)
          // if(e.layerX>12){
          //   return
          // }else
          // {
            let mouse = el.style.cursor;
            //更改默认样式
          //   el.style.backgroundColor = "rgba(189,220,251,0.88)";
            el.style.zIndex = 99;
            //对象解构赋值
            let {
              left: el_x,
              top: el_y,
              width: el_w,
              height: el_h,
            } = window.getComputedStyle(el);
            x = el_x;
            y = el_y;
            w = el_w;
            h = el_h;
            // console.log(x, y, w, h); // 坐标
            cx_start = e.clientX;
            cy_start = e.clientY;
            //绑定移动事件
            document.onmousemove = (e) => {
              cx_end = e.clientX;
              cy_end = e.clientY;
              //默认左下方向配置
              let x_move = cx_end - cx_start;
              let y_move = cy_end - cy_start;
              let direct = ["width", "height"];
              let pos = [w, h];
              let move = [x_move, y_move];
              let limit = 50;
              //判断鼠标的类型进行对应的操作
              switch (mouse) {
                case "e-resize":
                  direct = ["width"];
                  pos = [w];
                  move = [x_move];
                  break;
                case "s-resize":
                  direct = ["height"];
                  pos = [h];
                  move = [y_move];
                  break;
                case "move":
                  direct = ["left", "top"];
                  pos = [x, y];
                  limit = 0;
                  break;
              }
              handle_div(direct, pos, move, limit);
          // } // if
        
          };
          //取消移动事件
          document.onmouseup = (e) => {
            // console.log(e);
            //还原默认样式 -拖拽后
            el.style.zIndex = 9;
            //   el.style.backgroundColor = "rgba(189,220,251,0.88)";
            document.onmousemove = null;
          };
          /**
           * 操作DOM位置和大小方法
           * @param direct 方向
           * @param pos 尺寸/坐标
           * @param move 拖动距离
           * @param limit 限定范围
           */
          function handle_div(direct, pos, move, limit) {
            for (let i = 0; i < direct.length; i++) {
              let val = parseInt(pos[i]) + move[i];
              val = val <= limit ? limit : val;
              el.style[direct[i]] = val + "px";
            }
          }
        };
      } else {
        el.style.cursor = "default";
        //移除点击事件
        el.onmousedown = null;
        el.onmousemove = null;
      }
    },
  })

export const stopdrag = Vue.directive('stopdrag',{
   bind:(el, binding) =>{
      let element = el;
      element.onmousedown = function(e) {
          e.stopPropagation()
      }
   },
})  

这段代码即可

使用时:

<template>
// 大的框架可拖拽 <div v-if="uploadShow" class="uploadmode" v-drag>   // 下面内容组件区域不可拖拽 <div class="content" style="overflow-y:scroll;height:100%;" v-stopdrag> <uploadFile class="uploadstyle" style="" :files="filesArr" :folderName="folderName"></uploadFile> </div> <p style="margin:0;margin-top:10px;"><el-button type="primary" style="width:100%;" :disabled="filesArr&&filesArr.length>0 ? false : true" @click="ajaxconfirmupload">确定上传</el-button> </p> </div> </template> import "@/utils/drag"; // 引用即可

 

posted @ 2023-06-14 16:48  少哨兵  阅读(104)  评论(0编辑  收藏  举报