1. Introduction to project implementation

Vue Project Construction Refer to Webpack4 VUE Project Construction

Vuepress is the official document of vuepress.vuejs.org

Github Pages + gh-page

The project addressGithub.com/zxpsuper/vu…

File address zxpsuper.github. IO /vui-vue

Zxpsuper.github. IO /vui-vue/com…

In the stage of self exploration, looking forward to leaving your valuable advice!

2. Implement Throttle

  1. First, write a general function for anti-shake throttling
/** * @param {function} func function * @param {number} time * @param {Boolean} isDebounce is a security component * @param {this} CTX this points to */
const debounce = (func, time, isDebounce, ctx) = > {
    var timer, lastCall, rtn;
    if (isDebounce) {
        rtn = (. params) = > {
            if (timer) clearTimeout(timer);
            timer = setTimeout((a)= > {
                func.apply(ctx, params);
            }, time);
        };
    } else {
        rtn = (. params) = > {
            const now = new Date().getTime();
            if (now - lastCall < time && lastCall) return;
            lastCall = now;
            func.apply(ctx, params);
        };
    }
    return rtn;
};
Copy the code
  1. Using Abstract Components
export default {
    name: 'Throttle'.abstract: true.props: {
        time: {
            type: Number.default: 800,},events: {
            type: String.default: 'click',},isDebounce: {
            type: Boolean.default: false,
        },
    },
    created() {
        this.eventKeys = this.events.split(', '); // Separate events
        this.originMap = {}; // Store events for rerender to compare with child events
        this.debouncedMap = {}; // Save the anti-shake throttling event
    },
    render() {
        const vnode = this.$slots.default[0];
        this.eventKeys.forEach(key= > {
            const target = vnode.data.on[key];
            if (target === this.originMap[key] && this.debouncedMap[key]) {
                vnode.data.on[key] = this.debouncedMap[key];
            } else if (target) {
                this.originMap[key] = target;
                this.debouncedMap[key] = debounce(
                    target,
                    this.time,
                    this.isDebounce,
                    vnode
                );
                vnode.data.on[key] = this.debouncedMap[key]; // Override events for child components}});returnvnode; }};Copy the code

3. Use components

Global or component registration is required. Only the global registration code is shown here:

Vue.component("Throttle", Throttle);
Copy the code

Usage:

<Throttle :time="5000"  isDebounce>
    <span @click="decounceFunction">
        <Button color="purple" light>If the button</Button>
    </span>
</Throttle>
Copy the code

4. Existing problems and solutions

When a page element is updated (rendered) during the anti-shake throttling time (the page can be modified with a timer, such as a page countdown), this component executes again

this.debouncedMap[key] = debounce(target,this.time,this.isDebounce,vnode);
Copy the code

The current solution is to add v-once to the child element of this component, as follows:

<Throttle :time="5000"  isDebounce>
    <span @click="decounceFunction" v-once>
        <Button color="purple" light>If the button</Button>
    </span>
</Throttle>
Copy the code

There is a better way to solve this problem, please leave a comment in the comments section

5. Complete code

/* * @descript: a description component that can be used only if no other render is available during the waiting time. 2019-04-09 14:21:18 * @Last Modified by: super * @Last Modified time: 2019-10-24 16:37:43 */

const debounce = (func, time, isDebounce, ctx) = > {
    var timer, lastCall, rtn;
    if (isDebounce) {
        rtn = (. params) = > {
            if (timer) clearTimeout(timer);
            timer = setTimeout((a)= > {
                func.apply(ctx, params);
            }, time);
        };
    } else {
        rtn = (. params) = > {
            const now = new Date().getTime();
            if (now - lastCall < time && lastCall) return;
            lastCall = now;
            func.apply(ctx, params);
        };
    }
    return rtn;
};

export default {
    name: 'Throttle'.abstract: true.props: {
        time: {
            type: Number.default: 800,},events: {
            type: String.default: 'click',},isDebounce: {
            type: Boolean.default: false,
        },
    },
    created() {
        this.eventKeys = this.events.split(', ');
        this.originMap = {};
        this.debouncedMap = {};
    },
    render() {
        const vnode = this.$slots.default[0];
        this.eventKeys.forEach(key= > {
            const target = vnode.data.on[key];
            if (target === this.originMap[key] && this.debouncedMap[key]) {
                vnode.data.on[key] = this.debouncedMap[key];
            } else if (target) {
                this.originMap[key] = target;
                this.debouncedMap[key] = debounce(
                    target,
                    this.time,
                    this.isDebounce,
                    vnode
                );
                vnode.data.on[key] = this.debouncedMap[key]; }});returnvnode; }};Copy the code

conclusion

This article is a summary of the use of render and abstract components, if there are mistakes, hope to point out common progress.

More recommended

Advanced_front_end

Daily question

Webpack4 Build Vue application (createVue)

Canvas Advanced (1) Generation of two-dimensional code and scan code recognition

Canvas advanced (2) Write a NPM plug-in to generate a TWO-DIMENSIONAL code with logo

Canvas advanced (3) TS + Canvas rewrite “color discrimination” small game

Canvas advanced (four) to achieve a “scratch-off” game

VUI create log (a) – picture lazy load command implementation

Finally, I wish you all a happy holiday haha 😍