Use MouseMove event in Vue to get the mouse coordinate frequency reduction or event jam

When we use Vue for project development, Vue's introduction and ease of use make it possible for us to ignore Vue's lifecycle. Especially when using events, a slight surprise will cause an accident!

This article uses common drag and drop as a case.

When dragging a div element, it will obviously cause the div to follow the Snap when the mouse slides quickly.

Common code:

<script>
    export default {
        data() {
            return {
                                 // Test Data 
                testData: [
                    {value: '1'},
                    {value: '2'},
                    {value: '3'},
                    {value: '4'},
                    {value: '5'},
                    {value: '6'},
                    {value: '7'},
                    {value: '9'},
                    {value: '10'}
                ],
                /// ...
            };
        },
        methods: {
            testFun(name) {
                console.time(name + '-delay');
                for (let i = 0; i < 10240000; i++) {}
                console.timeEnd(name + '-delay');
            },
            // ...
        }
    }
</script>
<style>
  *::selection {
    background: none;
  }
  .box {
    position: fixed;
    z-index: 100;
    width: 200px;
    height: 80px;
  }
  .dargbtn {
    margin: 15px;
    color: #222222;
    background: #eee;
    cursor: pointer;
  }
  .box1 {
    background: #c0c;
  }
  .box2 {
    background: #0cc;
  }
</style>
Copy code

As shown above, testData is the test data (for data data loops), testFun is the test method (this method is used to lengthen the execution time of the function), and Style.

Box1 code:

<template>
    <div class="box box1"
         :style="box1Style"
         ref="box1"
    >
      <div class="dargbtn" @mousedown="box1ButtonDown">Click here to drag 1</div>
      <div class="delay-box">
        <span
          v-for="(item, index) in testData"
          :key="index"
          :data-testdata="testFun('box1')"
        >{{item.value}}</span>
      </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                // 1
                box1X: 0,
                box1Y: 0,
                box1L: 0,
                box1T: 0,
                box1CurrentX: 0,
                box1CurrentY: 0,
            };
        },
        computed: {
          box1Style() {
            return {
              top: this.box1CurrentY + 'px',
              left: this.box1CurrentX + 'px'
            };
          }
        },
        methods: {
          box1Start(e) {
            let dv = this.$refs.box1;
            this.box1X = e.clientX;
            this.box1Y = e.clientY;
    
            this.box1L = dv.offsetLeft;
            this.box1T = dv.offsetTop;
          },
          box1Move(e) {
            console.log('box1 move');
            let nx = e.clientX;
            let ny = e.clientY;
    
            let nl = nx - (this.box1X - this.box1L);
            let nt = ny - (this.box1Y - this.box1T);
    
                         // code key
            this.box1CurrentX = nl;
            this.box1CurrentY = nt;
          },
          box1End(e) {
            window.removeEventListener('mousemove', this.box1Move);
            window.removeEventListener('mouseup', this.box1End);
          },
          box1ButtonDown(e) {
            this.box1Start(e);
            window.addEventListener('mousemove', this.box1Move);
            window.addEventListener('mouseup', this.box1End);
          }
        }
    }
</script>
Copy code

Box2 code:

<template>
    <div class="box box2"
         :style="box2Style"
         ref="box2"
    >
      <div class="dargbtn" @mousedown="box2ButtonDown">Click here to drag 2</div>
      <div class="delay-box">
        <span
            v-for="(item, index) in testData2"
            :key="index"
            :data-testdata="testFun('box2')"
        >{{item.value}}</span>
      </div>
    </div>
</template>
<script>
    export default {
        data() {
            return {
                // 2
                box2X: 0,
                box2Y: 0,
                box2L: 0,
                box2T: 0,
                box2CurrentX: 0,
                box2CurrentY: 100
            };
        },
        computed: {
          box2Style() {
            return {
              top: '100px',
              left: '0px'
            };
          }
        },
        methods: {
            box2Start(e) {
                let dv = this.$refs.box2;
                this.box2X = e.clientX;
                this.box2Y = e.clientY;
                
                this.box2L = dv.offsetLeft;
                this.box2T = dv.offsetTop;
            },
            box2Move(e) {
                console.log('box2 move');
                let nx = e.clientX;
                let ny = e.clientY;
                let nl = nx - (this.box2X - this.box2L);
                let nt = ny - (this.box2Y - this.box2T);
                
                                 // code key
                this.box2CurrentX = nl;
                this.box2CurrentY = nt;
                let legendBox = this.$refs.box2;
                legendBox.style.left = nl + 'px';
                legendBox.style.top = nt + 'px';
            },
            box2End(e) {
                window.removeEventListener('mousemove', this.box2Move);
                window.removeEventListener('mouseup', this.box2End);
            },
            box2ButtonDown(e) {
                this.box2Start(e);
                window.addEventListener('mousemove', this.box2Move);
                window.addEventListener('mouseup', this.box2End);
            }
        }
    }
</script>
Copy code

Run the code as shown:

Code analysis

In the two pieces of code of the appeal, we found that the only difference is that box1 is the assignment of the style assignment by the computed property of the computed box2 is passed by methos The Move method assigns a value to the style assignment But the actual problem is not here, this is the bomb of the code!

There are two ways to bind data in Vue: calculating properties and methods.

Calculate attribute cache vs method

<p>Reversed message: "{{ reversedMessage() }}"</p>
 // in the component
methods: {
  reversedMessage: function () {
    return this.message.split('').reverse().join('')
  }
}
Copy code

We can define the same function as a method instead of a computed property. The end result of the two methods is indeed exactly the same. However, the difference isComputational properties are cached based on their dependencies. They are only reevaluated when the relevant dependencies change. This means that as long as the message has not changed, multiple access to the reversedMessage calculation property immediately returns the previous calculation without having to execute the function again.

This also means that the following computed properties will no longer be updated because Date.now() is not a reactive dependency:

computed: {
  now: function () {
    return Date.now()
  }
}
Copy code

In contrast, whenever a re-render is triggered, the calling method will always execute the function again.

Why do we need to cache? Suppose we have a computational property A with a large performance overhead, which requires traversing a huge array and doing a lot of calculations. Then we may have other computational properties that depend on A. If there is no cache, we will inevitably execute A's getter multiple times! If you don't want to have a cache, use a method instead.

to sum up

If you can use the calculation attribute to meet the demand priority, if you use the method, you need to pay attention to the method execution time.

example:

This article provides a demo to see:GitHub

*Copyright statement: This article is an original article and may not be reproduced without permission.

Intelligent Recommendation

MouseMove event of CheckedListBox

//The mouse moves to the patient's name and a message prompt box is displayed. private void checkedListBox_Patients_MouseMove(object sender, MouseEventArgs e) { int itemIndex = checkedListBox_Patients...

Javascript and jquery events-mousemove event mousemove

mousemove, an event that monitors the mouse movement on an element. If the mouse moves on the element, it is triggered approximately every 16 milliseconds. I think it’s an interesting element, b...

Cesium coordinate conversion and mouse event

Cesium Right Condom Coordinate System Conversion: Cesium Mouse Click to get the latitude and longitude Cesium gets level relationship Cesium mouse event: Create viewer: Mouse event: Roller event 2. Le...

Get the coordinates of the mouse event

Description: clientX and clientY properties: The horizontal and vertical coordinates of the mouse pointer in the viewport when the event occurs. pageX and pageY properties: The position of the mouse c...

Get mouse roller event

Why can't 80% of the code farmers can't do architects? >>>   Reprinted on: https: //my.oschina.net/mfkwfc/blog/136699...

More Recommendation

Mouse event, keyboard event, form event in Vue

Mouse event, keyboard event, form event, Mouse event, keyboard event, form event in Vue When we write the Vue project, we often use V-ON or @ to make event bindings, summarize the type of binding even...

Vue: Event processing (mouse event, keyboard event)

1. Event handling   Keyboard event Custom keyboard button Complete examples:...

About the mouseMove event of the QWidget subclass

Today, when I found that the mouse moved, no mouse movement event will be generated, but it will be triggered after the mouse is pressed. I read the qt documentation The same is said in the documentat...

Simple Shield Mousemove and Click event

2019 Unicorn Enterprise Heavy Glour Recruitment Python Engineer Standard >>> When a DOM object is binding the mouse click event and mouse drag event, the event trigger order is as follows mou...

Copyright  DMCA © 2018-2026 - All Rights Reserved - www.programmersought.com  User Notice

Top