предыстория истории:
Получен новый спрос, требуется VUE, в основном перетаскивание макета реализации, ключевые моменты:Перетаскивание одного компонента, перетаскивание компонента в одной строке и нескольких столбцах,Один компонент можно перетащить в строку и несколько столбцов., Перетаскивание одного компонента легко осуществить, главное перетащить компонент на другой, похожий на таблицу, а в некоторых случаях необходимо ограничитьПеретаскивание возможно только по горизонталиЯ собирал данные сами, экспериментировал и, наконец, придумал это.
Принцип в основном делится на две категории:
- HTML5 поставляется с API перетаскивания, доступные библиотеки:Vue.Draggable
- Используйте js для отслеживания положения мыши. Доступны следующие библиотеки: jquery ui
- Использовать точечное событие: нет (подробнее об этом ниже)
Недостатки каждого
Недостаток перетаскивания H5: невозможно ограничить перетаскивание в горизонтальном или вертикальном направлении.
Недостатки использования нативного js: много dom-операций, сложный код (jquery ui лучше упакован и может использоваться напрямую)
Но здесь возникает проблема, на этот раз требование состоит в том, чтобы реорганизовать перетаскивание на основе jquery ui с помощью vue, а затем использовать vue.draggable, но одно из требований состоит в том, чтобы ограничить перетаскивание в горизонтальном направлении, что смущает и не может использоваться.
Найти решение
Первая попытка:
<!DOCTYPE html>
<html>
<head>
<title>vue结合原生js实现拖动</title>
<script src="https://cdn.bootcss.com/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
<div class="ctn ctn1">
<div class="sub sub1" v-for="(site, index) in list1">
<div class="dragCtn fixed" :style="{ left: X+'px', top: Y+'px'}"
@mousedown="mousedown(site, $event)"
@mousemove.prevent='mousemove(site, $event)'
@mouseup='mouseup(site, $event)'>
拖动我
</div>
</div>
</div>
<div class="ctn ctn2">
<div class="sub sub2" v-for="(site, index) in list2"
@mouseenter='mouseenter(site, $event)'>
<div class="dragCtn">
{{ index }} : {{ site.name }}
</div>
</div>
</div>
</div>
<script>
new Vue({
el: '#app',
data: {
list1: [{name:1, index:0}],
list2: [{name:'a', index:0}, {name:'b', index:1}, {name:'c', index: 2}, {name:'d', index: 3}],
vm:'',
sb_bkx: 0,
sb_bky: 0,
is_moving: false,
X: 0,
Y: 0
},
methods: {
mousedown: function (site, event) {
var startx=event.x;
var starty=event.y;
this.sb_bkx=startx - event.target.offsetLeft;
this.sb_bky=starty - event.target.offsetTop;
this.is_moving = true;
},
mousemove: function (site, event) {
var endx=event.x - this.sb_bkx;
var endy=event.y - this.sb_bky;
var _this = this
if(this.is_moving){
this.X = endx;
this.Y = endy;
}
},
mouseup: function (e) {
this.is_moving = false;
},
mouseenter: function (){
console.log('鼠标进入')
}
}
})
</script>
<style>
.ctn{
line-height: 50px;
cursor: pointer;
font-size: 20px;
text-align: center;
float: left;
}
.sub:hover{
background: #e6dcdc;
color: white;
width: 100px;
}
.ctn1{
border: 1px solid green;
width: 100px;
}
.ctn2{
border: 1px solid black;
width: 100px;
margin-left: 50px;
}
.fixed{
width: 100px;
position: fixed;
background: red;
left: 0;
top: 0;
cursor: move;
}
</style>
</body>
</html>
Таким образом реализовано базовое перетаскивание, но при перетаскивании нельзя трогатьmouseenter Произошло событие, и мышь нужно перетаскивать очень медленно. Если вы будете двигаться быстрее, перетаскиваемый div не сможет за ним угнаться. Этот момент все еще сбивает с толку, и я надеюсь, что вы можете дать указатели. Потом я нашел в интернете много информации и библиотек классов, но они не могли полностью удовлетворить мои потребности, поэтому я приготовился писать их сам;
Первый — добавить событие mousedown к компоненту, а затем отслеживать положение мыши во время mousemove, а затем назначать его компоненту для реализации перетаскивания, но когда компонент перетаскивает в другой элемент, он не может отслеживать mouseenter.point-event:none
Атрибут, то есть для устранения исходного события мыши, вы можете инициировать событие mouerenter других компонентов, конкретное использование атрибута point-event может относиться сюда:
у-у-у-у. palms.com/WordPress/2…
Поскольку перетаскивание написано на нативном js, его можно ограничить перетаскиванием в горизонтальном направлении, а также можно вызвать событие mouseenter, что мне и нужно.
Псевдокод выглядит следующим образом:
mousedown: function (event, site) {
document.onmousemove=function (ev) {
// 移动的时候给元素增加 point-event:none 属性
...
}
document.onmouseup=function (ev) {
// up的时候 要移除point-event属性
...
}
}
Но тогда вышеуказанное требование должно быть совместимо с ie10, потому что point-event:none
Это атрибут H5, поэтому я поспешил проверить совместимость, случилось что-то ужасное,Свойство point-event совместимо только с ie11., черт!
Подумайте о других способах, а не об идеях, старая версия основана на перетаскивании jquery ui, поэтому посмотрите исходный код jquery ui, чтобы увидеть, как он реализован в перетаскивании.
Принцип реализации перетаскивания jQuery UI
Если вы не знакомы с методом перетаскивания пользовательского интерфейса jquery, вы можете сначала посмотреть на него. здесь
Посмотрите на следующий код:
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
drop: function( event, ui ) {
$( this ).html( "Dropped!" );
}
});
});
Ключевой вопрос перед тем, как судить о перетаскиваемом элементе$( "#draggable" ) Когда вы вошли в место, которое можно разместить?$( "#droppable" ) Да глядя на исходники его реализация просто тащит$( "#draggable" ) Следите за положением мыши, когда$( "#droppable" )Информация о положении области , пока мышь входит в область, она будет срабатывать.
Следуя этой мысли, проведение экспериментов может хорошо удовлетворить ваши собственные потребности!
Эффект реализации демо выглядит следующим образом:
Кодовый адрес: https://github.com/YalongYan/vue-drag-layout
Должна быть лучшая реализация макета перетаскивания, и вы можете предложить лучшие реализации.