Vue advocates manipulating the virtual DOM as little as possible as the real DOM. However, in the case of frequent dom manipulation, the experience is obviously not good. Use Js to manipulate the real DOM to achieve arbitrary drag and drop of divs. Here in order to reuse, written instructions, convenient for other pages to use, direct tuning instructions, do not need to write repeatedly. The directive is used to manipulate the DOM to avoid manipulating data.

PC:

<template>
  <div class="ha">
    <div class="box"  v-wahaha></div>
  </div>
</template>
<script>
export default {
  data(){
    return{x:"".y:"",}},mounted(){
    let box = document.querySelector('.box')
    let move = JSON.parse(window.localStorage.getItem("move"))
    box.style.left = move.x
    box.style.top = move.y
  },
  directives: {wahaha(el,binding){
      el.onmousedown = function(ev){
        var x = ev.clientX - el.offsetLeft;
        var y = ev.clientY - el.offsetTop;
        el.onmousemove = function(ev){
          window.localStorage.removeItem("move")
          this.x = ev.clientX - x + 'px';
          this.y = ev.clientY - y + "px" ;
          el.style.left = this.x
          el.style.top = this.y
          window.localStorage.setItem("move".JSON.stringify({x:this.x,y:this.y}))
        }
       el.onmouseup = function(ev){
       el.onmousemove = el.onmouseup = null;
       }
       return false; }}}}</script>
<style scoped>
.box{
  width: 200px;
  height: 200px;
  position: absolute;
  top: 100px;
  left: 100px;
  background: red;
}
</style>

Copy the code

Add the V-wahaha directive to the used div. There may be browser compatibility on PC, which can be optimized according to your needs. Illustration:

Mobile client:

Code copy is used directly.

<template>
  <div >
    <div id="box" v-wahaha></div>
  </div>
</template>
  <script type="text/javascript">
  export default {
    mounted(){// You can do this on your own
      this.$nextTick(() = >{
        var box = document.getElementById('box')
        var move = JSON.parse(window.localStorage.getItem("move"));
        box.style.left = `${move.x}px`;
        box.style.top = `${move.y}px`; })},directives: {drag(el,binding){
        var lenX // Define the X-axis relative to the finger click position from the left border of the box element
        var lenY // Define the y axis relative to the finger click position from the box element on the border
        var maxW // Define the maximum number of boxes that can be moved along the X-axis
        var maxH // Define the maximum value that the box can move along the y axis
        el.addEventListener('touchstart'.function(e){// When pressed
          maxW = e.srcElement.offsetParent.clientWidth-el.offsetWidth;
          maxH = e.srcElement.offsetParent.clientHeight-el.offsetHeight;
          var ev = e || window.event;
          var touch = ev.targetTouches[0];
          lenX = touch.clientX - el.offsetLeft;
          lenY = touch.clientY - el.offsetTop;
           el.addEventListener("touchmove",defaultEvent,false);// After the comment, the side bounces back
           window.localStorage.removeItem("move")
       })
        el.addEventListener('touchmove'.function(e){/ / drag
        var ev = e || window.event;
        var touch = ev.targetTouches[0];
        var left = touch.clientX - lenX;
        var top = touch.clientY - lenY;
        if(left<0){
           left=0;
        }else if (left>=maxW) {
            left=maxW;
        }
        if(top <0){
            top =0;
        }else if (top >=maxH) {
            top =maxH;
        }
        el.style.left = left + 'px';
        el.style.top = top + 'px';
        window.localStorage.setItem("move".JSON.stringify({x:left,y:top}))
      })
        el.addEventListener('touchend'.function(){ / / let go
        document.removeEventListener("touchmove",defaultEvent);
        })
        function defaultEvent(e) { e.preventDefault(); }}}},</script>
</style>
Copy the code

Illustration:

The above is a partial command, can only be used in the current page command. The following are global directives that can be used on all pages.

Vue.directive("wahaha".(el,binding) = >{
    var lenX // Define the X-axis relative to the finger click position from the left border of the box element
    var lenY // Define the y axis relative to the finger click position from the box element on the border
    var maxW // Define the maximum number of boxes that can be moved along the X-axis
    var maxH // Define the maximum value that the box can move along the y axis
    el.addEventListener('touchstart'.function(e){// When pressed
      maxW = e.srcElement.offsetParent.clientWidth-el.offsetWidth;
      maxH = e.srcElement.offsetParent.clientHeight-el.offsetHeight;
      var ev = e || window.event;
      var touch = ev.targetTouches[0];
      lenX = touch.clientX - el.offsetLeft;
      lenY = touch.clientY - el.offsetTop;
       el.addEventListener("touchmove",defaultEvent,false);// After the comment, the side bounces back
       window.localStorage.removeItem("move")
    })
    el.addEventListener('touchmove'.function(e){/ / drag
    var ev = e || window.event;
    var touch = ev.targetTouches[0];
    var left = touch.clientX - lenX;
    var top = touch.clientY - lenY;
    if(left<0){
       left=0;
    }else if (left>=maxW) {
        left=maxW;
    }
    if(top <0){
        top =0;
    }else if (top >=maxH) {
        top =maxH;
    }
    el.style.left = left + 'px';
    el.style.top = top + 'px';
    window.localStorage.setItem("move".JSON.stringify({x:left,y:top}))
    })
    el.addEventListener('touchend'.function(){ / / let go
    document.removeEventListener("touchmove",defaultEvent);
    })
    function defaultEvent(e) { e.preventDefault(); }})Copy the code

There are good optimization welcome to point out, there is help to give a support bar…