inspiration

Testing during project development raised an optimization issue **’ every click pops up a prompt ‘(what fuck? Shouldn’t a prompt come out once you click on it?) ** Well, I’m a professional programmer, so the first thing I thought of was using the anti-shake function.

What is anti-shake?

First, use a simple example to introduce what is the shake, play LOL friends should know that the hero will only have a forward shake when releasing skills, so this skill can be called the shake. Imagine if a hero’s ability doesn’t have any forward swing then the other players don’t have any way to restrain him and anticipate him. So in programming, we can write an anti-shake function to prevent some 213 users from clicking all the time causing the prompt to appear indefinitely.

Image stabilization function

You can try it by copying the code directly to the F12 Console

Function debounce(fn, time) {// Let timer = null // initialize return function(... Args) {// Return function to receive arguments if (timer)clearTimeout(timer) // If the timer has a value then clear it and retry timer = setTimeout(() => {// start the timer after two seconds Fn.apply (this, args) // Return the function this to the actual caller (in this case func)}, time) } } let func=debounce(()=>{console.log('1')},1000) func()Copy the code

What is throttling?

To illustrate the simplest example, throttling is a skill CD. When you release a skill, it takes N seconds to release it. In a program, it is usually used for DOM operations after listening for certain special events. Such as: scroll bar mouse movement events.

Throttling function

Function throttle(fn, time) {// Accept a function and delay time let pre = 0 // initialize return function(... Args) {let now = +new Date() // define a variable to receive the latest time rub if (now - pre > time) {// Determine if the latest time minus the initialization time is greater than the delay Fn. apply(this, args) // Return the function this to the actual caller (in this case func) pre = now // assign the start time to the last end time}}}Copy the code

Source of component ideas

All the functions have been written, but IT occurred to me that there are so many click events in a project that I need to do the anti-shake and throtting operations. Even if I package the functions in a JS, it will be very troublesome to import the functions in each page. Is there a way of gradual change? I was in baidu search once found this article to share. Blog.csdn.net/userkang/ar…

This article is very well written and the principle is to use VUE’s abstract component approach, but it can’t be used ‘directly’ in my projects because our projects are based on the elementUI framework and all events and methods are not stored in vNode.data.on as they are native ElementUI events in vnode.com ponentOptions. Listeners, so I secondary packaging for this component, its adaptation HTML native label and elementUI label.

So I made the following changes

  1. ADAPTS to native and elementUI tags

  2. You can choose components freely, anti-shake or throttling to meet different business requirements

    import Vue from 'vue' const debounce = (func, time, ctx, immediate) => { let timer const rtn = (... params) => { clearTimeout(timer) if (immediate) { let callNow = ! timer console.log(timer) timer = setTimeout(() => { timer = null }, time) if (callNow) func.apply(ctx, params) } else { timer = setTimeout(() => { func.apply(ctx, params) }, time) } } return rtn } const throttle = (func, time, ctx, immedidate) => { let pre if (immedidate) { pre = 0 } else { pre = +new Date() } return function(args) { let now = +new Date() if (now - pre > time) { func.apply(ctx, args) pre = now } } } Vue.component('Debounce', { abstract: true, props: ['time', 'events', 'immediate', 'way', 'proto'], Created () {enclosing eventKeys = this. Events && enclosing events. The split (', ') enclosing types = this. Way | | 'stabilization' enclosing the prototype = This. Proto | | 'element'}, render () {const vnode = this. $slots. The default [0] / / if the default doesn't preach events, events will all binding plus stabilization if (! this.eventKeys) { this.prototype == 'element' ? this.eventKeys = Object.keys(vnode.componentOptions.listeners) : If (prototype == 'element') {this.prototype == 'element') {this.prototype == 'element'; this.eventKeys.forEach(key => { vnode.componentOptions.listeners[key] = debounce( vnode.componentOptions.listeners[key],  this.time, vnode, this.immediate ) }) } else { this.eventKeys.forEach(key => { vnode.data.on[key] = debounce( vnode.data.on[key], this.time, vnode, this.immediate ) }) } } else { if (this.prototype == 'element') { this.eventKeys.forEach(key => { vnode.componentOptions.listeners[key] = throttle( vnode.componentOptions.listeners[key], this.time, vnode, this.immediate ) }) } else { this.eventKeys.forEach(key => { vnode.data.on[key] = throttle( vnode.data.on[key], this.time, vnode, this.immediate ) }) } } return vnode } })Copy the code
    Import '@/common/debounce' /** * @param {native or Element, default to Element and any value other than element is native} proto * @param } event * @param {delay time} time * @param {select choke, default is choke, and any value that is not choke is choke} way * PS @param {immediate */ //element usage < debounce event='click' :time='500' :immediate='true' way=' buffer 'proto='element'> <el-button @click="submitCheck()" > Confirm commit </el-button> </Debounce> // native usage <Debounce event='click' :time='500' :immediate='true' way=' throttle 'proto=' HTML '> < button@click ="submitCheck()" > Confirm commit </button> </Debounce> 'Copy the code