iView之Select組件的優化

iViewSelect組件在機能上的優化

    我們公司的組件庫是基於iView 比較早的版本修改后的僅供公司內部運用的組件庫,因此在運用的過程當中就會碰到一些題目。接下來本文會對照Select組件在機能上做出的優化。

Debounce函數

    我們先來回憶一下debounce函數的運用場景:在前端頁面我們會碰到一些頻仍觸發的事宜;比方

鼠標的挪動
mousemove事宜;

window對象的resizescroll事宜;

keydown,keyup事宜;

現實的運用過程當中我們可以不須要每次觸發事宜的時刻都去響應當事宜,我們每每須要當用戶住手操縱若干ms後去響應事宜。這個時刻我們就須要用到debounce函數了。下面是一段debounce函數

export function debounce(fn) {
    let waiting;
    return function() {
        if (waiting) return;
        waiting = true;
        const context = this,
            args = arguments;
        const later = function() {
            waiting = false;
            fn.apply(context, args);
        };
        this.$nextTick(later);
    };
}

這段代碼的意義的意義是當DOM更新後去響應這個事宜,而且DOM更新后只會實行一次
有了這些學問的預備我們便可以來談談運用這個組件碰到的機能題目了。

低版本iviewSelect組件碰到的題目

    在運用低版本的組件過程當中,當數據量很大比方某個select選擇器內里有500條以至更多的數據時,舉行隱約搜刮有可以卡死頁面,封閉頁面有耽誤。

湧現該題目的緣由

    在Select組件的mounted鈎子中有三個監聽,分別是組件增加,刪除,和選中時監聽事宜。在監聽事宜中會去遍歷Select當中的一切子組件做出響應的轉變。

//監聽子組件的移除
this.$on('remove',() => {
    if (!this.remote) {
        this.modelToQuery();
        this.$nextTick(() => this.broadcastQuery(''));
    } else {
        this.findChild((child) => {
            child.updateSearchLabel();   // #1865
            child.selected = this.multiple ? this.model.indexOf(child.value) > -1 : this.model === child.value;
        });
    }
    this.slotChange();
    this.updateOptions(true);
})

查找這個監聽的關照對象發明恰是Select的子組件在燒毀或者是建立時關照父組件做出響應的變化。

//組件燒毀時關照父組件
beforeDestroy () {
    this.dispatch('iSelect', 'remove');
    this.$off('on-select-close', this.onSelectClose);
    this.$off('on-query-change',this.onQueryChange);
}

那末題目就出在這裏了,當有大批的子組件時,每個組件移除,父組件須要遍歷一次。如許就拖累機能。

處理辦法

    既然前面提到debounce函數,想必人人應當想到要怎樣處理了。運用debounce函數可以處理這個題目,我們只須要一切子組件燒毀時關照父組件一次就夠了。引入debounce函數后經本人測試基本上處理了卡頓以及卡死的題目,代碼以下。

//select組件mounted函數當中去監聽 append 、remove 事宜
this.$on('append', this.debouncedAppendRemove());
this.$on('remove', this.debouncedAppendRemove());
//引入debounce函數
debouncedAppendRemove(){
    return debounce(function(){
        if (!this.remote) {
            this.modelToQuery();
            this.$nextTick(() => this.broadcastQuery(''));
        } else {
            this.findChild((child) => {
                child.updateSearchLabel();   // #1865
                child.selected = this.multiple ? this.model.indexOf(child.value) > -1 : this.model === child.value;
            });
        }
        this.slotChange();
        this.updateOptions(true);
    });
}

其他細節

    低版本中子組件的監聽事宜沒有移撤除,高版本的有移除。

mounted () {
    this.$on('on-select-close', this.onSelectClose);
    this.$on('on-query-change',this.onQueryChange);
}

beforeDestroy () {
    this.$off('on-select-close', this.onSelectClose);
    this.$off('on-query-change',this.onQueryChange);
}
    原文作者:River
    原文地址: https://segmentfault.com/a/1190000014575626
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞