[Vue.js] Draggable (Movable) Element


Use Vue.js custom directive to make HTML element draggable.

The key points in the code:

  • When users mouse down the HTML element, record the position of the HTML element and the initial mouse position.
  • When users mouse move the element, calculate the distance of initial position and current position, and then update the position of the element accordingly.
  • When users release the button (mouse up) over the element, remove registered event listener.

Demo

index.html | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>Vue.js Draggable (Movable) Element Demo</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <style>#app{width: 200px; height: 200px; background: yellow;}</style>
</head>
<body>

<div id="app" v-draggable>Drag Me</div>

<script src="https://unpkg.com/vue@2.1.10/dist/vue.js"></script>
<script src="app.js"></script>
</body>
</html>
app.js | repository | view raw
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
'use strict';

Vue.directive('draggable', {
  bind: function (el) {
    el.style.position = 'absolute';
    var startX, startY, initialMouseX, initialMouseY;

    function mousemove(e) {
      var dx = e.clientX - initialMouseX;
      var dy = e.clientY - initialMouseY;
      el.style.top = startY + dy + 'px';
      el.style.left = startX + dx + 'px';
      return false;
    }

    function mouseup() {
      document.removeEventListener('mousemove', mousemove);
      document.removeEventListener('mouseup', mouseup);
    }

    el.addEventListener('mousedown', function(e) {
      startX = el.offsetLeft;
      startY = el.offsetTop;
      initialMouseX = e.clientX;
      initialMouseY = e.clientY;
      document.addEventListener('mousemove', mousemove);
      document.addEventListener('mouseup', mouseup);
      return false;
    });
  }
})

new Vue({
  el: '#app'
})

Tested on:

  • Chromium Version 55.0.2883.87 Built on Ubuntu , running on Ubuntu 16.10 (64-bit)
  • Vue.js 2.1.10.

References:

[1]Custom Directives — Vue.js