场景:实现窗体可以鼠标拖拽、放大缩小的功能
技术: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