首页 > 其他分享 >vue封装包含区域内不可拖拽的可拖拽组件

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

时间:2023-06-14 16:55:14浏览次数:53  
标签:el style vue 封装 move width let 拖拽

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

实现方式很简单  

直接看代码

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"; // 引用即可

 

标签:el,style,vue,封装,move,width,let,拖拽
From: https://www.cnblogs.com/zbbk/p/17480756.html

相关文章

  • vue3 css ts 双重弹跳加载动画
    /双重弹跳加载动画*/效果如同页面https://codepen.io/yjx123/pen/zYMvbML<ahref="javascript:void(0)"@click="startLoading"><inline-svg:src="getAssetPath(iconPath)"></inline-svg><div:style="{......
  • 【React工作记录一百零五】springBoot+vue实现登录操作和JWT验证
    前言大家好我是歌谣今天继续进行前后端的一个学习目前进入的是javaweb部分今天来聊聊登录部分和JWT验证部分的书写用户登录loginControllerpackagecom.itheima.controller;importcom.itheima.pojo.Emp;importcom.itheima.pojo.Result;importcom.itheima.service.EmpSer......
  • 2023-06-14 记录一下vue组件如何调用App.vue里面的方法(代码来至chatGpt)
    可以通过在子组件中使用$emit方法来触发App.vue中的方法。具体步骤如下:在App.vue中定义一个方法<script>exportdefault{methods:{appMethod(){console.log('调用了App.vue中的方法')}}}</script>在子组件中使用$emit方法触发该方......
  • vue watch deep 用法
    简单案例<template><div><h1>watchdeep</h1><p>obj:{{obj}}</p><p>调用watch次数:{{times}}</p><button@click="chgObj">改变对象</button></div></t......
  • Vue3中循环任务优化方案
    需求在使用循环任务时,往往需要使用到setInterval方法。其接受三个参数,分别是1.具体执行的函数2.执行时间间隔3.传递个函数的参数,并返回一个id,后续可以使用这个id来停止循环的执行。具体的使用可以查阅MDN。在实际开发中,很容易重复创建相同的interval实例,进行反复的执行,并且在......
  • Vue.js 组件基础 #yyds干货盘点#【yyds干货盘点】
    学习目录:Vue.js简介Vue.js实例与数据绑定Vue.js计算属性和侦听器Vue.js条件渲染和列表渲染Vue.js事件处理Vue.js表单输入绑定Vue.js组件基础Vue.js组件通信Vue.js插槽Vue.js动态组件和异步组件Vue.js自定义指令Vue.js过渡和动画Vue.js混入Vue.js自定义事件和v-model......
  • VUE游戏开发:使用Box2D模拟球体的飞行和撞击特效
    本节,我们将利用Box2d引擎在页面中实现球体飞行和撞击效果。在现实中我们向外抛出一个球时,它在重力加速度的情况下会飞出一个弧线,撞到物体后它会反弹折射,我们利用Box2D可以在页面里模拟这些特性。我们将在页面里绘制一个小球,然后设置一些障碍物,我们用鼠标控制小球向外抛出的方向,小球......
  • VUE+WebPack游戏设计:'乘法防线'游戏设计
    从本节开始,我们进入新的游戏设计阶段。本次游戏设计,我们需要使用html5专有的canvas,也就是画布对象。同时为了便于在canvas上绘制图案,我们引入一个第三方库叫做CreateJS,它能帮我们管理在canvas上绘制的各种图形。乘法防线的游戏目的是为了帮助小学生学习乘法运算法则。游戏的主要内......
  • 转:Vue项目解决跨域
    Vue项目解决跨域  使用vue配置代理服务器解决跨域连接 Vue·修改启动端口   ......
  • Vue-router跳转和location.href有什么区别
    vue-router使用pushStat进行路由更新,不刷新页面,静态跳转;使用diff算法,按需加载,减少dom操作,同一个页面跳转或者路由跳转异步加载this.$nextTick(()=>{获取url})使用location.href来跳转,简单方便,但是刷新了页面;不同页面间跳转可以直接获取当前路径......