一. 主要思路
1.1通过绑定自定义的指令,获取需要拖动的父子元素,
1.2.添加鼠标按下事件onmousedown,计算出鼠标的相对位置odiv.offsetLeft与odiv.offsetTop,
1.3.鼠标移动事件onmousemove当鼠标移动时触发,移动的时候相对位置加上偏移距离得到对应的坐标点,
1.4.odiv.style.left与 odiv.style.top动态给对应的元素添加位置样式,
1.5.onmouseup():鼠标抬起事件。当鼠标抬起触发,// 移除对鼠标移动事件的监听
document.onmousemove = null; document.onmouseup = null;
1.6.切换页面初始化加载坐标位置保持页面垂直居中对齐// 初始化初始坐标
二. 分布实施
2.1 template结构,cursor:move->鼠标移动上变成可拖拽的样式,绑定唯一ID 获取初始化坐标原点
html
<template>
<div>
<div class="AllTree">
<!-- cursor:move->鼠标移动上变成可拖拽的样式 -->
<!-- 通过绑定唯一ID 获取初始化坐标原点 -->
<vue2-org-tree
style="#fafafa;cursor:move"
v-drag
id="dragFather"
:data="treeData"
/>
</div>
</div>
</template>
2.2 数据结构
javascript
data() {
return {
// 数据
treeData: {
id: 0,
name: "",
children: []
},
};
},
2.3 activated()切换页面初始化加载坐标位置保持页面垂直居中对齐,获取id
javascript
// 切换页面初始化加载坐标位置保持页面垂直居中对齐
activated() {
// 初始化初始坐标
const dialogHeaderEl = document.querySelector('#dragFather')
dialogHeaderEl.style.left=0 + 'px';
dialogHeaderEl.style.top=0 + 'px';
},
2.4 自定义拖拽指令
javascript
// 开启拖拽的指令
directives: {
drag: {
// 指令的定义
bind: function (el) {
var odiv = el // 获取当前元素
let isMouseDown=false;//鼠标按下标记
// onmousedown():鼠标按下事件。当鼠标按下时触发。
odiv.onmousedown = (e) => {
if(e.button===0&&!isMouseDown){
// 算出鼠标相对元素的位置
let offsetLeft = odiv.offsetLeft
let offsetTop = odiv.offsetTop
var disX = e.clientX
var disY = e.clientY
// onmosemove():鼠标移动事件。当鼠标移动时触发
document.onmousemove = (e) => {
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
// 结构沿X轴发生翻转X轴坐标变成从左到右计算的时候相反计算,
var left = disX - e.clientX
var top = e.clientY - disY
// 移动当前元素
odiv.style.left = (left + offsetLeft) + 'px'
odiv.style.top = (top + offsetTop) + 'px'
}
isMouseDown=true
}
// onmouseup():鼠标抬起事件。当鼠标抬起触发
// e.button===0代表点击左键
document.onmouseup = (e) => {
if(e.button===0){
isMouseDown=false;
// 移除对鼠标移动事件的监听
document.onmousemove = null
document.onmouseup = null
}
}
}
}
}
},
2.5 style样式
css
<style scoped>
::-webkit-scrollbar {
/*隐藏滚轮*/
display: none !important;
}
</style>
<style lang="less" >
// 整体的结构设置
.AllTree {
font-size: 12px;
transform: rotateY(180deg);
overflow: auto;
// 修改组件内置的样式
.org-tree-node-label .org-tree-node-label-inner {
cursor: pointer;
padding: 0;
}
// 子节点
.org-tree-container {
position: relative; /*定位*/
display: flex;
justify-content: center;
align-items: center;
min-height: 600px;
}
}
// 节点样式
.ReNode {
height: 40px;
min-width: 50px;
transform: rotateY(180deg);
background-color: rgb(238, 244, 246);
display: flex;
line-height: 40px;
padding: 0 10px;
}
</style>
三. 特别注意
由于此图结构是从右到左展示,市面上的树形结构一般是由从左到右,从上到下;要求的结构是从右到左所以在进行编写的时候利用 transform: rotateY(180deg);进行了翻转x轴发生了变化所以此处对于坐标的计算有所不同
四.代码汇总
html
<template>
<div>
<div class="AllTree">
<!-- cursor:move->鼠标移动上变成可拖拽的样式 -->
<!-- 通过绑定唯一ID 获取初始化坐标原点 -->
<vue2-org-tree
style="#fafafa;cursor:move"
v-drag
id="dragFather"
:data="treeData"
/>
</div>
</div>
</template>
<script>
export default {
data() {
return {
// 数据
treeData: {
id: 0,
name: "",
children: []
},
};
},
// 切换页面初始化加载坐标位置保持页面垂直居中对齐
activated() {
// 初始化初始坐标
const dialogHeaderEl = document.querySelector('#dragFather')
dialogHeaderEl.style.left=0 + 'px';
dialogHeaderEl.style.top=0 + 'px';
},
// 开启拖拽的指令
directives: {
drag: {
// 指令的定义
bind: function (el) {
var odiv = el // 获取当前元素
let isMouseDown=false;//鼠标按下标记
// onmousedown():鼠标按下事件。当鼠标按下时触发。
odiv.onmousedown = (e) => {
if(e.button===0&&!isMouseDown){
// 算出鼠标相对元素的位置
let offsetLeft = odiv.offsetLeft
let offsetTop = odiv.offsetTop
var disX = e.clientX
var disY = e.clientY
// onmosemove():鼠标移动事件。当鼠标移动时触发
document.onmousemove = (e) => {
// 用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
// 结构沿X轴发生翻转X轴坐标变成从左到右计算的时候相反计算,
var left = disX - e.clientX
var top = e.clientY - disY
// 移动当前元素
odiv.style.left = (left + offsetLeft) + 'px'
odiv.style.top = (top + offsetTop) + 'px'
}
isMouseDown=true
}
// onmouseup():鼠标抬起事件。当鼠标抬起触发
// e.button===0代表点击左键
document.onmouseup = (e) => {
if(e.button===0){
isMouseDown=false;
// 移除对鼠标移动事件的监听
document.onmousemove = null
document.onmouseup = null
}
}
}
}
}
},
};
</script>
<style scoped>
::-webkit-scrollbar {
/*隐藏滚轮*/
display: none !important;
}
</style>
<style lang="less" >
// 整体的结构设置
.AllTree {
font-size: 12px;
transform: rotateY(180deg);
overflow: auto;
// 修改组件内置的样式
.org-tree-node-label .org-tree-node-label-inner {
cursor: pointer;
padding: 0;
}
// 子节点
.org-tree-container {
position: relative; /*定位*/
display: flex;
justify-content: center;
align-items: center;
min-height: 600px;
}
}
// 节点样式
.ReNode {
height: 40px;
min-width: 50px;
transform: rotateY(180deg);
background-color: rgb(238, 244, 246);
display: flex;
line-height: 40px;
padding: 0 10px;
}
</style>