如何在 vue draggable 中保持拖动项目直到释放
How to keep dragging item at former position until release in vue draggable
我正在使用 vuedraggable 在 vue 中实现一个嵌套层组件。
我试着让它靠近 Adobe 的图层面板(例如在 Illustrator 中)。
期望的行为是:
拖动项目时,它会保持在原位,只有一条黑线表示释放拖动后项目将插入的位置。
黑线可以通过 vue draggable 的 ghost 样式来实现。但是如何防止项目在拖动时从其原始位置移除?
Adobe Illustrator layers example
本质上,在单击时创建项目的副本,然后将所选项目设置为不可见。在鼠标悬停时,隐藏副本并使项目再次可见。
一个例子:
ball.onmousedown = function(event) { // (1) start the process
// (2) prepare to moving: make absolute and on top by z-index
var ball2 = ball; //set the balls current position so it doesn't appear to move
ball.style.position = 'absolute';
ball.style.visibility = "hidden"; //make the moving item invisible
document.body.append(ball);
// ...and put that absolutely positioned ball under the pointer
moveAt(event.pageX, event.pageY);
// centers the ball at (pageX, pageY) coordinates
function moveAt(pageX, pageY) {
ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
}
// (3) move the ball on mousemove
document.addEventListener('mousemove', onMouseMove);
// (4) drop the ball, remove unneeded handlers
ball.onmouseup = function() {
ball.style.visibility = "visible"; //makes the moved ball visible again
ball2.style.visibility = "hidden"; //makes the copy invisible
document.removeEventListener('mousemove', onMouseMove);
ball.onmouseup = null;
};
};
我现在使用与 类似的方法,但没有直接操作 DOM。
相反,我复制了列表中的项目...
start(event) {
// Make a clone of the choosen item and add it to the
// layers list.
const index = event.oldIndex
const item = this.layers[index]
this.layers.splice(index + 1, 0, {
...item,
// Vue requires unique keys.
id: item.id + '_clone',
// Set a isClone flag to be able to delete the clone
// afterwards.
isClone: true
})
},
...然后删除
end() {
// Delete the clone from the layers.
this.layers = this.layers.filter(layer => !layer.isClone)
}
这里是完整的例子:https://jsfiddle.net/arnoson/587L0nx9/45/
我仍然不确定这是否是最优雅的解决方案,希望有一个内置的方法来做到这一点。
所以我最终使用了 sl-vue-tree
它基本上完成了模拟 Adobe Illustrators 图层面板所需的一切。
我正在使用 vuedraggable 在 vue 中实现一个嵌套层组件。 我试着让它靠近 Adobe 的图层面板(例如在 Illustrator 中)。
期望的行为是: 拖动项目时,它会保持在原位,只有一条黑线表示释放拖动后项目将插入的位置。
黑线可以通过 vue draggable 的 ghost 样式来实现。但是如何防止项目在拖动时从其原始位置移除?
Adobe Illustrator layers example
本质上,在单击时创建项目的副本,然后将所选项目设置为不可见。在鼠标悬停时,隐藏副本并使项目再次可见。
一个例子:
ball.onmousedown = function(event) { // (1) start the process
// (2) prepare to moving: make absolute and on top by z-index
var ball2 = ball; //set the balls current position so it doesn't appear to move
ball.style.position = 'absolute';
ball.style.visibility = "hidden"; //make the moving item invisible
document.body.append(ball);
// ...and put that absolutely positioned ball under the pointer
moveAt(event.pageX, event.pageY);
// centers the ball at (pageX, pageY) coordinates
function moveAt(pageX, pageY) {
ball.style.left = pageX - ball.offsetWidth / 2 + 'px';
ball.style.top = pageY - ball.offsetHeight / 2 + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY);
}
// (3) move the ball on mousemove
document.addEventListener('mousemove', onMouseMove);
// (4) drop the ball, remove unneeded handlers
ball.onmouseup = function() {
ball.style.visibility = "visible"; //makes the moved ball visible again
ball2.style.visibility = "hidden"; //makes the copy invisible
document.removeEventListener('mousemove', onMouseMove);
ball.onmouseup = null;
};
};
我现在使用与
相反,我复制了列表中的项目...
start(event) {
// Make a clone of the choosen item and add it to the
// layers list.
const index = event.oldIndex
const item = this.layers[index]
this.layers.splice(index + 1, 0, {
...item,
// Vue requires unique keys.
id: item.id + '_clone',
// Set a isClone flag to be able to delete the clone
// afterwards.
isClone: true
})
},
...然后删除
end() {
// Delete the clone from the layers.
this.layers = this.layers.filter(layer => !layer.isClone)
}
这里是完整的例子:https://jsfiddle.net/arnoson/587L0nx9/45/
我仍然不确定这是否是最优雅的解决方案,希望有一个内置的方法来做到这一点。
所以我最终使用了 sl-vue-tree 它基本上完成了模拟 Adobe Illustrators 图层面板所需的一切。