SoFunction
Updated on 2025-04-05

Analysis of anti-shake analysis of vue global registration custom instruction

Global registration custom command anti-shake

1. Create a js file first

Create a file and place it in the src/directives folder

export default (vue) => {
  /**
 * Binding method
    * @param {Object} el - The element the directive is bound to.
 * @param {Object} binding - An vue directive object
 */
   ('debounce', { //Anti-shake function command      inserted: function(el, binding) {
        let timer;
        ("click", () => {
          if (timer) {
            clearTimeout(timer);
          }
          timer = setTimeout(() => {
          //Keypoint: The parameter binding passed by the custom instruction of vue If it is a function, it is executed by      (). Through the above example, you can also pass events, binding objects, etc.            ();
          }, 1000);
        });
      }
   })
}

2. Register in

import Debounce from './directives/' //Undershake custom commandDebounce(Vue)

3. Use

Add this command to the button button in the component to achieve anti-shake

v-debounce="getTableData"

Use of vue anti-shake

Anti-shake function

function debounce(fn, immediate = true) {
  let timer;
  return function () {
    if (timer) clearTimeout(timer);
    if (immediate) {
      let bool = !timer;
      timer = setTimeout(() => (timer = 0), 300);
      return bool && (this, [...arguments]);
    }
    timer = setTimeout(() => (this, [...arguments]), 300);
  };
}
export default {
  debounce,
};

Use directly in vue

import utils from "./utils/index";
methods:{
    // Add debounce manually    btnHandler1: utils["debounce"](function (...rest) {
      ("2222 ", this, rest);
    }),
}

Use advanced components in vue

Use abstract components to transform incoming buttons, rewrite events for buttons, and add anti-shake function;

import Vue from 'vue'
// ctx 【context context bound this pointer】const debounce = (func, time, ctx, immediate = true) => {
  let timeout
  return function (...params) {
    if (timeout) clearTimeout(timeout)
    if (immediate) {
      var callNow = !timeout
      timeout = setTimeout(() => {
        timeout = null
      }, time)
      if (callNow) (ctx, params)
    } else {
      timeout = setTimeout(function () {
        (ctx, params)
      }, time)
    }
  }
}
// Only one component can be bound, multiple components cannot be bound('Debounce', {
  abstract: true,//Abstract components, stateless,  props: ['time', 'events', 'immediate'],
  created () {
     =  && (',')
     = {}
     = {}
  },
  render () {
    // The component is wrapped with proxy object, you can understand [this];    // Take out the virtual node, the first one is by default, that is, if multiple subcomponents are passed in the higher-order component, only the first one is displayed    const vnode = this.$[0]
    // If there is no events transmitted by default, add anti-shake to all binding events    if (!) {
       = ()
    }
    ((key) => {
      const target = [key]
      if (target === [key] && [key]) {
        [key] = [key]
      } else if (target) {
        [key] = target
        [key] = debounce(target, , vnode, )
        [key] = [key]
      }
    })
    return vnode
  }
})
    <Debounce events="click" time="300">
      <button @click="clickHandler(1,2,3)" :btnval="'val'">click1</button>
    </Debounce>

Use custom directives in vue

// Command [Anti-shake]("debounce", {
  // Call only once, and call it when the element is bound for the first time  // el【binding element】, binding【a related object】, vnode【virtual node generated by vue compilation】  // After beforemount, before mounted;  // init events&lifecycle [Initialize events and lifecycle]  bind(el, binding, vnode, oldVnode) {
    (el, binding, vnode, oldVnode);
    let { value } = binding;
    let [target, time] = value;
    const debounced = debounce(target, time, vnode);
    ("click", debounced);
  },
  // Called when the bound element is inserted into the parent node (only guarantees that the parent node exists, but does not necessarily insert the document)  inserted() {},
  // Called when the vnode of the component is updated  update() {},
  componentUpdated() {},
  unbind(el) {
    (el, "el");
    ("click", el._debounced);
  },
});
use
 	&lt;button
      v-debounce="[
        () =&gt; {
          btnHandler();
        },
        300,
      ]"
    &gt;
      Click
    &lt;/button&gt; 
    &lt;button v-if="testcom" v-debounce="[btnHandler, 300]"&gt;Click&lt;/button&gt;

The above is personal experience. I hope you can give you a reference and I hope you can support me more.