1. 思路
本篇主要实现了视图方面的拖拽效果:

涉及到的主要知识点为vue自定义指令.
在app根元素中放一个预留的dragTip元素, 当触发拖拽时, 将触发元素的内容放入dragTip元素中, 这样就可以实现图中的效果.
2. 代码实现
vue中有两种自定义指令: 全局和组件内, 可以根据指令的适用范围来考虑写在全局或是组件中. 那在本篇中使用的组件内的自定义指令:
2.1 js代码:
directives: {
drag: {
// bind: 指令第一绑定到元素时调用, 其中el就是指绑定的元素, binding就是与这个指令相关的一些数据
bind (el, binding) {
el.onmousedown = function (e) {
// let disX = e.clientX - el.offsetLeft
let disY = e.clientY - el.offsetTop
let width = el.offsetWidth
let newDiv = document.getElementById('dragTip')
document.onmousemove = function (e) {
let l = el.offsetLeft
let t = e.clientY - disY
el.classList.add('isDragging')
newDiv.innerText = el.innerText
newDiv.style.top = t + 'px'
newDiv.style.left = l + 'px'
newDiv.style.width = width + 'px'
newDiv.classList.add('isDragging')
binding.value(el)
}
document.onmouseup = function (e) {
newDiv.innerHTML = ''
newDiv.classList.remove('isDragging')
el.classList.remove('isDragging')
document.onmousemove = null
document.onmouseup = null
}
}
}
}
}
2.2 HTML代码
treeItem.vue
<template>
<li class="tree-item-li">
<div
v-drag="greet"
class="tree-item-label"
@click="activeItem"
@mouseup="exchange"
>{{nodes.label}}</div>
<ul v-if="isEnd" class="tree-item-ul">
<tree-item
v-for="(item, index) in nodes.nodes"
:key="index"
:nodes="item">
</tree-item>
</ul>
</li>
</template>
app.vue
<template>
<div id="app">
<router-view/>
<div id="dragTip"></div>
</div>
</template>
2.3 CSS
禁止了用户选择文字, 避免对拖拽造成影响
body {
user-select: none;
}
.router-view {
display: block;
}
li, ul {
list-style: none;
text-align: left;
margin: 0 0 0 10px;;
padding: 0;
}
.treeMenu {
border: 1px solid #666;
width: 600px;
padding-left: 20px;
padding-right: 10px;
}
.tree-item-li {
padding: 5px 0;
}
.tree-item-label {
height: 30px;
line-height: 30px;
}
.tree-item-label:hover {
cursor: pointer;
}
.tree-item-label.active,
.tree-item-label.isDragging {
background: #666;
color: #fff;
}
#dragTip {
display: none;
user-select: none;
}
#dragTip.isDragging {
position: absolute;
background-color: #666;
color: #fff;
opacity: 0.6;
display: block;
}
3. TODO
本来以为写起来很简单, 但是要考虑的地方还是有点多的, 所以只做到了视图这一步, 下一篇争取把视图=>数据给写完
网友评论