Draggable component

HTML

<div id="vue">
  <draggable header="Drag me">Hello</draggable>
  <draggable header="Drag me">World</draggable>
  <draggable header="Drag me">
    <draggable header="Drag me">Nested!<draggable header="Drag me">World</draggable></draggable>
  </draggable>
</div>

SCSS

body{
  overflow-x:hidden;
}
.draggable{
  position:relative;
  background:white;
  box-shadow:0px 1px 1px rgba(0,0,0,0.5);
  transition:box-shadow 0.2s;
  margin-bottom:10px;
  &.dragging{
    box-shadow:0px 3px 8px rgba(0,0,0,0.5);
    z-index:200;
  }
  .header{
    background:#444;
    color:white;
    padding:10px;
    cursor:move;
    user-select:none;
  }
  .content{
    padding:20px;
  }
}

JavaScript

let z = 1 //This shared variable is necessary so that the last dragged component is always on top
Vue.component('draggable', {
	template:`
  	<div class="draggable" :class="{dragging}" :style="{top:top + 'px', left:left + 'px', zIndex:z}" @mousedown="updateZ">
      <div class="header" @mousedown="dragStart">
        {{header}}
      </div>
      <div class="content">
    		<slot></slot>
      </div>
    </div>
  `,
  props:['header'],
  data(){
  	return {
    	top:0,
      left:0,
      z:1,
      dragging:false
    }
  },
  methods:{
  	move(e){
      //prevent component from being dragged out of view
      if(e.pageY > 0 && e.pageY < document.body.clientHeight){
      	this.top += e.movementY
      }
    	if(e.pageX > 0 && e.pageX < document.body.clientWidth){
      	this.left += e.movementX
      }
    },
  	dragStart(){
    	this.dragging = true
      //Need to add listeners to the document rather than the component, otherwise there will be problems if the mouse moves too fast
      document.addEventListener('mousemove', this.move)
      document.addEventListener('mouseup', this.dragStop)
      document.addEventListener('mouseleave', this.dragStop)
    },
    dragStop(){
    	this.dragging = false
    	document.removeEventListener('mousemove', this.move)
      document.addEventListener('mouseup', this.dragStop)
      document.removeEventListener('mouseleave', this.dragStop)
    },
    updateZ(){
    	this.z = z += 1
    }
  }
})
new Vue({
	el:'#vue'
})