使用v-drag实现div盒子拖拽放大缩小

场景:实现窗体可以鼠标拖拽、放大缩小的功能

技术:vue2.x
UI框架:ant design vue1.78

效果
拖拽在这里插入图片描述
在这里插入图片描述
放大缩小:
在这里插入图片描述

template代码块

    <div class="maskLayer"  v-drag id="containerVeastTree">
        <div class="catalogueHeader">
          <div>
            目录树
            <a-icon type="close" style="float: right; font-size: 15px; padding-top: 4px" />
          </div>
        </div>
        <a-select v-model="DefaultTree" class="catalogueSelect" @change="TreeChange">
          <a-select-option :value="item.schemeId" v-for="(item, index) in TreeList" :key="index">
            {{ item.schemeName }}
          </a-select-option>
        </a-select>
        <a-input placeholder="输入关键字进行过滤" v-model="filterText" allowClear>
          <a-icon slot="prefix" type="search" />
        </a-input>
        <veastTree
          id="divTree"
          class="veastTreecss"
          nodekey="id"
          :treeData="treeData"
          :replaceFields="replaceFields"
          :showcheckbox="true"
          :DefaultCheckKey="DefaultCheckKey"
          :expandonclicknode="false"
          :showTree="showTree"
          :replaceSettings="replaceSettings"
          :sertCurrent="currentKey"
          :filterText="filterText"
          @nodeDataClick="nodeClick"
          @checkChange="checkChange"
        />
        <div id="tz" @mousedown="dragEagle">
          <div title="" id="move_tz"></div>
        </div>
    </div>

script代码块

export default {
  name: "HelloWorld",
  // 自定义指令给div加 v-drag 实现可拖动
  directives: {
    drag(el, bindings) {
      el.onmousedown = function (e) {
        if (e.target.parentNode.className === "catalogueHeader") {
          var disx = e.pageX - el.offsetLeft;
          var disy = e.pageY - el.offsetTop;
          document.onmousemove = function (e) {
            el.style.left = e.pageX - disx + "px";
            el.style.top = e.pageY - disy + "px";
          };
          document.onmouseup = function () {
            document.onmousemove = document.onmouseup = null;
          };
        }
      };
    },
  },
  data() {
    return {
      DefaultTree: "",
      TreeList: [],
      //树搜索
      filterText: "",
      treeData: [],
      //树字段替换
      replaceFields: {
        children: "children",
        label: "name",
        key: "id",
        type: "type",
      },
      DefaultCheckKey: [],
      //点击是否高亮
      showTree: false,
      //处理业务复杂情况下的属性
      replaceSettings: {
        //默认是否显示图标
        isImage: true,
        //是否显示新增按钮
        isAddsubimt: false,
        //是否显示编辑按钮
        isEditsubimt: false,
        //是否显示删除按钮
        isDeletesubimt: false,
        //是否存在业务性绑定比较强的按钮
        isBusinessSubmit: false,
      },
      //选中的节点 高度并且定位  iSsertCurrnetKey是否有选中  sertCurrnetKey放guid
      currentKey: { sertCurrnetKey: "", iSsertCurrnetKey: false },
      //树搜索
      filterText: "",
    };
  },
  methods: {
    dragEagle: function (e) {
      var targetDiv = document.getElementById("containerVeastTree"); //e.target.parentNode.parentNode;.children[0]
      var scrollerHeightdiv = document.getElementById("divTree"); //
      //得到点击时该容器的宽高:
      var targetDivWidth = targetDiv.offsetWidth;
      var targetDivHeight = targetDiv.offsetHeight;
      var scrollerHeight = scrollerHeightdiv.offsetHeight;
      var startX = e.clientX;
      var startY = e.clientY;
      const that = this;
      document.onmousemove = function (e) {
        e.preventDefault();
        //得到鼠标拖动的宽高距离:取绝对值
        var distX = Math.abs(e.clientX - startX);
        var distY = Math.abs(e.clientY - startY);
        //往右方拖动:
        if (e.clientX > startX) {
          targetDiv.style.width = targetDivWidth + distX + "px";
        }
        if (e.clientY > startY) {
          targetDiv.style.height = targetDivHeight + distY + "px";
          scrollerHeightdiv.style.height = scrollerHeight + distY + "px";
        }

        //往左方拖动:
        if (e.clientX < startX) {
          targetDiv.style.width = targetDivWidth - distX + "px";
        }
        if (e.clientY < startY && e.clientY >= 349) {
          targetDiv.style.height = targetDivHeight - distY + "px";
          scrollerHeightdiv.style.height = scrollerHeight - distY + "px";
        }
        //设置最大最小范围:不能无限制缩放,影响体验
        // if (parseInt(targetDiv.style.width) >= 500) {
        //   targetDiv.style.width = 500 + 'px'
        // }

        // if (parseInt(targetDiv.style.height) >= 700) {
        //   targetDiv.style.height = 700 + 'px'
        // }
      };

      document.onmouseup = function () {
        document.onmousemove = null;
      };
    },
    TreeChange(e) {},
    nodeClick() {},
    checkChange() {},
  },
};

style代码块(使用了less, lang=“less” scoped)

.maskLayer {
  position: absolute;
  top: 80px;
  right: 22px;
  width: 282px;
  min-width: 300px;
  background-color: #2b2c2d;
  color: #fff;
  filter: alpha(Opacity=80);
  -moz-opacity: 0.5;
  opacity: 0.8;
  z-index: 101;
  .catalogueHeader {
    cursor: move;
    width: 100%;
    padding: 0;
    margin: 0;
    background: #000;
    div:nth-child(1) {
      padding: 4px;
      font-size: 13px;
    }
  }
  .catalogueSelect {
    width: 100%;
  }
}
.veastTreecss {
  min-height: 50px;
  overflow-x: hidden;
  overflow-y: auto;
}
#move_tz {
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAABGdBTUEAALGPC/xhBQAAAF5JREFUCB1jYEADq1at4r927dpOJmRxkKC+vv5ORkbGG3BxkODNmzdPXL9+fSJWwf///zNfvnx5CTNM+79//05qaGgUAXUtBeoQYARZBDJTU1MzH6SSiYlJaMaMGYEA7E42FFiHq5AAAAAASUVORK5CYII=)
    no-repeat;
  position: absolute;
  width: 9px;
  height: 8px;
  cursor: se-resize;
  z-index: 100;
  right: 0;
  bottom: 0;
}
#tz {
  bottom: 0;
  width: 100%;
  height: 13px;
  cursor: n-resize;
  z-index: 110;
  position: absolute;

  background-color: #2b2c2d;
}
#tz:hover {
  background-color: #000;
}

注意点

1.拖拽主要是使用mousedown,v-drag,其中directives方法的e.target.parentNode.className ===‘类名’ 是鼠标可以拖拽的区域
2.dragEagle方法里document.onmousemove 可以自定义需要拖动的方向
3.需要是复杂的拖拽以及放大缩小可以使用vue-grid-layout插件实现,目前我使用的版本是2.3.12

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值