最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Element的穿梭框數(shù)據(jù)量大時(shí)點(diǎn)擊全選卡頓的解決方案

 更新時(shí)間:2021年10月31日 10:00:01   作者:綿雨喚  
本文主要介紹了Element的穿梭框數(shù)據(jù)量大時(shí)點(diǎn)擊全選卡頓的解決方案,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

現(xiàn)象:我們渲染了9999條數(shù)據(jù),由于transfer組件會(huì)一次性渲染所有數(shù)據(jù),所以一次性渲染這么多,卡個(gè)幾十秒很正常好吧。所以懶加載或者分頁是基本操作,方案二是分頁操作。

懶加載的方式可以用EUI的無限滾動(dòng):https://element.eleme.cn/

即便我們做了懶加載之后,點(diǎn)擊全選依舊是卡頓6秒以上,所以方案一解決的是:即便做了懶加載或者分頁操作后,用戶點(diǎn)擊分頁,依舊會(huì)卡頓幾秒的情況。

這個(gè)是因?yàn)閠ransfer的源碼中‘全選判斷'代碼性能差的原因,方案一就是修改transfer的源碼。

我提交了一個(gè)pr,地址是: hhttps://github.com/ElemeFE/element/pull/20282

方案一:復(fù)制EUI的transfer組件,然后進(jìn)行修改,再引入項(xiàng)目目錄

EUI的transfer組件目錄路徑:node_modules\element-ui\packages\transfer,復(fù)制文件夾,然后放入vue項(xiàng)目路徑的

在調(diào)用EUI的transfer的地方引入公共的組件transfer,

<template>
  <Transfer v-model="value" :data="data"></Transfer>
</template>

<script>
import Transfer from '../common/transfer'
export default {
  components:{
    Transfer:Transfer
  },
 //省略
</script>

開始修改transfer代碼:

打開src/common\transfer\src\transfer-panel.vue的組件,

找到updateAllChecked函數(shù),updateAllChecked函數(shù)作用是:我們點(diǎn)擊一個(gè)item就需要判斷,看代碼注釋。

updateAllChecked() {
      /*
        源碼
        this.checkableData是對(duì)象數(shù)組  我們需要的是每個(gè)對(duì)象中的key
        所以checkableDataKeys保存著對(duì)象的key的數(shù)組 含義是'可通過點(diǎn)擊進(jìn)行選擇的item項(xiàng)'的集合
      */
      let start = new Date().getTime();
      const checkableDataKeys = this.checkableData.map(
        item => item[this.keyProp]
      );

      this.allChecked =
        checkableDataKeys.length > 0 &&
      /*
        從2.4.0到現(xiàn)在都沒改變 誒,不得不說開發(fā)團(tuán)隊(duì)是真的忙啊
        this.checked保存著'用戶通過點(diǎn)擊item選中的item數(shù)組'
        如果this.checked存在著checkableDataKeys的每一項(xiàng)的話,那么allChecked就是true,但凡有一項(xiàng)不存在就為false。allChecked代表是否全部選中了。
        這里的時(shí)間復(fù)雜度是n^2,狠垃圾
      */
      checkableDataKeys.every(item => this.checked.indexOf(item) > -1);
      console.log("updateAllCheckedEnd", new Date().getTime() - start);

    },

來看源碼的耗時(shí):

然后我們開始重寫updateAllChecked函數(shù):

updateAllChecked() {
      /*
        修改
        這里就是高效數(shù)組中含有另一個(gè)數(shù)組的元素的算法
        構(gòu)建元素對(duì)象
      */
      let start = new Date().getTime();
      let checkableDataKeys = this.checkableData.map((item) => {
        let keyProps = {};
        keyProps[item[this.keyProp]] = true;
        return keyProps;
      });
      // 通過對(duì)象的k-v對(duì)應(yīng),n(1)的方式尋找數(shù)組中是否存在某元素
      this.allChecked =
        checkableDataKeys.length > 0 &&
        this.checked.length > 0 &&
        this.checked.every((item) => checkableDataKeys[item]);
      // 上面被注釋的源碼是最耗時(shí)的,所有一直看耗時(shí)就可以了
      console.log("updateAllCheckedEnd", new Date().getTime() - start);
    },

這樣性能就高好多了,其實(shí)就是基本的前端算法題,目測EUI的開發(fā)者是因?yàn)閼胁挪粚懙摹?/p>

來看修改代碼后的耗時(shí):

明顯快多了。

接下來是文件:\src\common\transfer\src\main.vue,找到addToRight函數(shù)

addToRight() {
      let currentValue = this.value.slice();
      const itemsToBeMoved = [];
      const key = this.props.key;
      let start = new Date().getTime();
      // 此處套了兩層循環(huán),耗時(shí)長
      this.data.forEach((item) => {
        const itemKey = item[key];
        if (
          this.leftChecked.indexOf(itemKey) > -1 &&
          this.value.indexOf(itemKey) === -1
        ) {
          itemsToBeMoved.push(itemKey);
        }
      });
      console.log("addToRightEnd", new Date().getTime() - start);

      currentValue =
        this.targetOrder === "unshift"
          ? itemsToBeMoved.concat(currentValue)
          : currentValue.concat(itemsToBeMoved);
      this.$emit("input", currentValue);
      this.$emit("change", currentValue, "right", this.leftChecked);
    },

移動(dòng)選中的耗時(shí):

修改addToRight函數(shù),

addToRight() {
      let start = new Date().getTime();
      let currentValue = this.value.slice();
      const itemsToBeMoved = [];
      const key = this.props.key;

      // 修改
      let leftCheckedKeyPropsObj = {};
      this.leftChecked.forEach((item, index) => {
        leftCheckedKeyPropsObj[item] = true;
      });

      let valueKeyPropsObj = {};
      this.value.forEach((item, index) => {
        valueKeyPropsObj[item] = true;
      });
      this.data.forEach((item) => {
        const itemKey = item[key];
        if ( leftCheckedKeyPropsObj[itemKey] && !valueKeyPropsObj[itemKey] ) {
          itemsToBeMoved.push(itemKey);
        }
      });
      console.log("addToRightEnd", new Date().getTime() - start);

      currentValue =
        this.targetOrder === "unshift"
          ? itemsToBeMoved.concat(currentValue)
          : currentValue.concat(itemsToBeMoved);
      this.$emit("input", currentValue);
      this.$emit("change", currentValue, "right", this.leftChecked);
    },

移動(dòng)選中耗時(shí):

耗時(shí)明顯減少了,這方案的前提就是懶加載或者分頁,我試了一下10w的數(shù)據(jù)量,依舊是不錯(cuò)的。

方案二:分頁操作

分析

checkBox-group有個(gè)check數(shù)組(用來記錄已經(jīng)選中的item數(shù)組)和renderItem數(shù)組(實(shí)際渲染的item,由于是分頁,所有不會(huì)渲染所有),如果`check數(shù)組`中有`renderItem數(shù)組`的一項(xiàng),那么該項(xiàng)就會(huì)被標(biāo)記為已選,否則是未選。實(shí)現(xiàn)原理就是單純的check數(shù)組和renderItem數(shù)組進(jìn)行比較。

當(dāng)用戶點(diǎn)擊全選的時(shí)候,check數(shù)組變成上萬條數(shù)據(jù)的數(shù)組,此時(shí)我們渲染了100條數(shù)據(jù),那么就要進(jìn)行10000x100級(jí)別的循環(huán),這就是耗時(shí)的原因所在。

其實(shí),頁面只渲染了100條數(shù)據(jù),我們沒必要將上萬條數(shù)據(jù)一次性放入check數(shù)組中,我們只需要把這100條數(shù)組放入check數(shù)組,顯示這100條數(shù)據(jù)為已選即可。當(dāng)頁面渲染了更多數(shù)據(jù)的同時(shí),將新增的數(shù)據(jù)添加進(jìn)check數(shù)組即可。這樣性能大大提升。

方案

我采用的方案如下:

1.只顯示100條數(shù)據(jù)。

2.下拉顯示下100條數(shù)據(jù),上拉顯示上100條數(shù)據(jù)。

3.當(dāng)下拉或者上拉增加渲染數(shù)據(jù)的同時(shí),把新增數(shù)據(jù)添加進(jìn)check數(shù)組。

這些只是大致思路,我已經(jīng)實(shí)現(xiàn)了。還有很多細(xì)節(jié)要處理,想要完善,還得利用對(duì)象的鍵值對(duì)實(shí)現(xiàn)刪除等。

到此這篇關(guān)于Element的穿梭框數(shù)據(jù)量大時(shí)點(diǎn)擊全選卡頓的解決方案的文章就介紹到這了,更多相關(guān)Element 穿梭框卡頓內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JS數(shù)組Array常用方法匯總+實(shí)例

    JS數(shù)組Array常用方法匯總+實(shí)例

    這篇文章主要介紹了JS數(shù)組Array常用方法匯總和實(shí)例,JavaScript創(chuàng)建數(shù)組的方式,找數(shù)組元素,數(shù)組去重,實(shí)現(xiàn)數(shù)組排序需要的朋友可以參考下
    2022-05-05
  • Vue?列表過濾與排序的實(shí)現(xiàn)

    Vue?列表過濾與排序的實(shí)現(xiàn)

    這篇文章主要介紹了Vue?列表過濾與排序的實(shí)現(xiàn),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值需要的小伙伴可以參考一下
    2022-05-05
  • vue3.2新增指令v-memo的基本使用教程

    vue3.2新增指令v-memo的基本使用教程

    ue3.2新增了一個(gè)指令v-memo,引入這個(gè)指令的目的是幫助大家更好的為我們的應(yīng)用做性能優(yōu)化,下面這篇文章主要給大家介紹了關(guān)于vue3.2新增指令v-memo基本使用的相關(guān)資料,需要的朋友可以參考下
    2022-09-09
  • 使用vue與jquery實(shí)時(shí)監(jiān)聽用戶輸入狀態(tài)的操作代碼

    使用vue與jquery實(shí)時(shí)監(jiān)聽用戶輸入狀態(tài)的操作代碼

    本文是腳本之家小編給大家?guī)淼氖褂胿ue與jquery實(shí)時(shí)監(jiān)聽用戶輸入狀態(tài),實(shí)現(xiàn)效果是input未輸入值時(shí),按鈕禁用狀態(tài),具體操作代碼大家參考下本文吧
    2017-09-09
  • vue如何動(dòng)態(tài)給data中添加變量

    vue如何動(dòng)態(tài)給data中添加變量

    這篇文章主要介紹了vue如何動(dòng)態(tài)給data中添加變量問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue-cli3 配置開發(fā)與測試環(huán)境詳解

    vue-cli3 配置開發(fā)與測試環(huán)境詳解

    這篇文章主要介紹了vue-cli3 配置開發(fā)與測試環(huán)境詳解,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2019-05-05
  • vue-ajax小封裝實(shí)例

    vue-ajax小封裝實(shí)例

    下面小編就為大家?guī)硪黄獀ue-ajax小封裝實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • 給vue項(xiàng)目添加ESLint的詳細(xì)步驟

    給vue項(xiàng)目添加ESLint的詳細(xì)步驟

    本篇文章主要介紹了給vue項(xiàng)目添加ESLint的詳細(xì)步驟,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-09-09
  • Vue3+Canvas實(shí)現(xiàn)簡易的貪吃蛇游戲

    Vue3+Canvas實(shí)現(xiàn)簡易的貪吃蛇游戲

    貪吃蛇作為一個(gè)經(jīng)典的小游戲,是很多人兒時(shí)的記憶,當(dāng)時(shí)的掌機(jī)、諾基亞手機(jī)里面都有它的身影。本文將用Vue3?Canvas來復(fù)刻一下這款游戲,感興趣的可以了解一下
    2022-07-07
  • 詳解vue2.0+vue-video-player實(shí)現(xiàn)hls播放全過程

    詳解vue2.0+vue-video-player實(shí)現(xiàn)hls播放全過程

    這篇文章主要介紹了詳解vue2.0+vue-video-player實(shí)現(xiàn)hls播放全過程,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03

最新評(píng)論

河东区| 富平县| 拉萨市| 铁力市| 怀柔区| 星座| 广饶县| 纳雍县| 正蓝旗| 晋中市| 伊宁市| 万山特区| 香港 | 高邮市| 策勒县| 延川县| 英德市| 萍乡市| 信丰县| 平江县| 吕梁市| 嘉荫县| 亚东县| 万山特区| 上蔡县| 永顺县| 安泽县| 宝鸡市| 甘泉县| 淮南市| 长宁区| 玉龙| 米泉市| 霞浦县| 福海县| 富民县| 黑山县| 漾濞| 金山区| 常德市| 哈巴河县|