欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

antd的select下拉框因為數(shù)據(jù)量太大造成卡頓的解決方式

 更新時間:2020年10月31日 10:50:12   作者:燈光下的投影  
這篇文章主要介紹了antd的select下拉框因為數(shù)據(jù)量太大造成卡頓的解決方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧

相信用過antd的同學(xué)基本都用過select下拉框了,這個組件數(shù)據(jù)量少的時候很好用,但是當(dāng)數(shù)據(jù)量大的時候,比如大幾百條上千條甚至是幾千條的時候就感覺一點都不好用了,卡的我懷疑人生,一點用戶體驗都沒有了。

當(dāng)然這不是我想去優(yōu)化它的動力,主要是公司業(yè)務(wù)人員和后端的同事也無法忍受,于是我只能屈從于他們的淫威。。。。

想要優(yōu)化肯定要知道為什么會卡,初步判斷就是數(shù)據(jù)量過大導(dǎo)致渲染option組件的時間過長導(dǎo)致卡頓,于是想要不卡只能限制渲染的數(shù)據(jù)數(shù)量。

我的想法是這樣的:任何時候都只渲染前100條數(shù)據(jù)以保證不卡頓,然后當(dāng)需要搜索的時候?qū)暮笈_拿到的數(shù)據(jù)進行過濾,也只取前100條,然后當(dāng)select框不下拉的時候也就是失焦的時候?qū)?shù)據(jù)回復(fù)原樣。

下面是我的具體實現(xiàn):

先從后臺拿到數(shù)據(jù),保存到變量fundList中(作為數(shù)據(jù)源,永遠(yuǎn)不改動),然后取其中的前100條數(shù)據(jù)保存到fundList_中,用來下拉框的數(shù)據(jù)渲染

{fundList_.map(item => <Option key={item.fund} value={item.fund}>{item.name}</Option>)}

這是整個select組件:

<Select
 mode="multiple"
 maxTagCount={0}
 placeholder="請選擇"
 showSearch={true}
 onBlur={this.handleOnBlur}
 onSearch={this.handleOnSearch}
 allowClear={true}
 onChange={(value)=>{this.modalChangeSelect(value,'1')}}
 style={{width:'223px'}}
 value={record['1']||undefined}
 disabled={this.state.visibleType==='修改'?true:false}
>
 {fundList_.map(item => <Option key={item.fund} value={item.fund}>{item.name}</Option>)}
</Select>

然后寫search里面的功能

handleOnSearch = value => {
 // 函數(shù)節(jié)流,防止數(shù)據(jù)頻繁更新,每300毫秒才搜索一次
 let that = this
 if (!this.timer) {
  this.timer = setTimeout(function(){
  that.searchValue(value)
  that.timer = null
  },300)
 }
 }
searchValue = (value) => {
 const datas = [] 
 const {fundList} = this.state
 // 對fundList進行遍歷,將符合搜索條件的數(shù)據(jù)放入datas中
 fundList.forEach(item => {
 if (item.name.indexOf(value) > -1) {
  datas.push(item)
 }
 })
 // 然后只顯示符合搜索條件的所有數(shù)據(jù)中的前100條
 this.setState({fundList_: datas.slice(0,100)})
}

當(dāng)select失焦的時候,將數(shù)據(jù)恢復(fù)原樣(只顯示fundList中的前100條數(shù)據(jù)):

handleOnBlur = () => {
 this.setState({fundList_: this.state.fundList.slice(0,100)})
 }

到此這個功能就大體實現(xiàn)了,已經(jīng)不存在卡頓的問題了,但是這個方法并不是完美的,這不,業(yè)務(wù)就說了,你只顯示了前100條數(shù)據(jù),但是我有時候不通過搜索功能查找某條數(shù)據(jù),我要在所有的數(shù)據(jù)里面直接找到那條數(shù)據(jù)(業(yè)務(wù)也不嫌累。。。),我要顯示所有的數(shù)據(jù)。

這下就難辦了,因為卡頓就是渲染太多的數(shù)據(jù)造成的,所以還是不能一次性渲染所有的數(shù)據(jù),然后怎么辦呢,我也不知道怎么辦吶。于是上網(wǎng)搜索了一下別人碰到相關(guān)問題的解決辦法,于是還真的找到了。

思路是這樣的:

同樣是先只展示前100條數(shù)據(jù)(這個沒辦法,想要不卡只能這樣),然后當(dāng)滾動條滾到第100條數(shù)據(jù)也就是滾到底部的時候再增加100條,就這樣一直到展示所有的數(shù)據(jù),下面是具體的實現(xiàn)步驟:

1、先造點假數(shù)據(jù):

const data = [];
for (let i = 0; i < 1000; i++) {
 data.push(`test${i}`);
}
// 一開始只展示前100條數(shù)據(jù)
const data_ = data.slice(0, 100);

2、渲染出來

<Select
 showSearch
 allowClear
 onPopupScroll={this.handleScroll}
 style={{ width: 200 }}
 placeholder="Select a person"
 optionFilterProp="children"
 onChange={this.onChange}
 onFocus={this.onFocus}
 onBlur={this.onBlur}
 onSearch={this.onSearch}
 filterOption={(input, option) =>
 option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
 }
>
 {optionData.map(item => (
 <Option value={item}>{item}</Option>
 ))}
</Select>

3、寫滾動條滾動的功能

在這里就要說一下select里面的一個參數(shù)了,就是 onPopupScroll,以前沒有注意到,看到別人提醒的時候才發(fā)現(xiàn)。有了它就可以實現(xiàn)滾動實時刷新數(shù)據(jù)了。

然后寫滾動的功能

handleScroll = e => {
 e.persist();
 const { target } = e;
 // scrollHeight:代表包括當(dāng)前不可見部分的元素的高度
 // scrollTop:代表當(dāng)有滾動條時滾動條向下滾動的距離,也就是元素頂部被遮住的高度
 // clientHeight:包括padding但不包括border、水平滾動條、margin的元素的高度
 const rmHeight = target.scrollHeight - target.scrollTop;
 const clHeight = target.clientHeight;
 // 當(dāng)下拉框失焦的時候,也就是不下拉的時候
 if (rmHeight === 0 && clHeight === 0) {
  this.setState({ scrollPage: 1 });
 } else {
 // 當(dāng)下拉框下拉并且滾動條到達(dá)底部的時候
 // 可以看成是分頁,當(dāng)滾動到底部的時候就翻到下一頁
  if (rmHeight < clHeight + 5) {
  const { scrollPage } = this.state;
  this.setState({ scrollPage: scrollPage + 1 });
  //調(diào)用處理數(shù)據(jù)的函數(shù)增加下一頁的數(shù)據(jù)
  this.loadOption(scrollPage + 1);
  }
 }
 };
 loadOption = pageIndex => {
 const { pageSize, keyWords } = this.state;
 // 通過每頁的數(shù)據(jù)條數(shù)和頁數(shù)得到總的需要展示的數(shù)據(jù)條數(shù)
 const newPageSize = pageSize * (pageIndex || 1);
 let newOptionsData = [],len; // len 能展示的數(shù)據(jù)的最大條數(shù)
 if (data.length > newPageSize) {
  // 如果總數(shù)據(jù)的條數(shù)大于需要展示的數(shù)據(jù)
  len = newPageSize;
 } else {
  // 否則
  len = data.length;
 }
 // 如果有搜索的話,就走這里
 if (!!keyWords) {
  let data_ = data.filter(item => item.indexOf(keyWords) > -1) || [];
  data_.forEach((item, index) => {
  if (index < len) {
   newOptionsData.push(item);
  }
  });
 } else {
  data.forEach((item, index) => {
  if (index < len) {
   newOptionsData.push(item);
  }
  });
 }
 this.setState({ optionData: newOptionsData });
 };

4、搜索功能:

和我剛開始的一樣

onSearch = val => {
 console.log("search:", val);
 if (!this.timer) {
  const that = this;
  this.timer = setTimeout(function() {
  that.searchValue(val);
  that.timer = null;
  }, 300);
 }
 this.setState({ keyWords: val });
 };
 searchValue = value => {
 let data_ = data.filter(item => item.indexOf(value) > -1);
 if (data_.length > 100 || value === "") {
  data_ = data_.slice(0, 100);
 }
 this.setState({ optionData: data_ });
 };

5、 然后失焦的時候:

handleOnBlur = () => {
 this.setState({fundList_: this.state.fundList.slice(0,100)})
 }

總的代碼:

import React from "react";
import ReactDOM from "react-dom";
import "antd/dist/antd.css";
import "./index.css";
import { Select } from "antd";

const { Option } = Select;

const data = [];
// let pageSize = 100,scrollPage = 1,keyWords = '',optionData = [];
for (let i = 0; i < 1000; i++) {
 data.push(`test${i}`);
}

const data_ = data.slice(0, 100);

class App extends React.Component {
 state = {
 pageSize: 100,
 scrollPage: 1,
 keyWords: "",
 optionData: data_
 };

 onChange = value => {
 console.log(`selected ${value}`);
 };

 onBlur = () => {
 console.log("blur");
 this.setState({ optionData: data_ });
 };

 onFocus = () => {
 console.log("focus");
 };

 onSearch = val => {
 console.log("search:", val);
 if (!this.timer) {
  const that = this;
  this.timer = setTimeout(function() {
  that.searchValue(val);
  that.timer = null;
  }, 300);
 }
 this.setState({ keyWords: val });
 };
 searchValue = value => {
 let data_ = data.filter(item => item.indexOf(value) > -1);
 if (data_.length > 100 || value === "") {
  data_ = data_.slice(0, 100);
 }
 this.setState({ optionData: data_ });
 };
 loadOption = pageIndex => {
 const { pageSize, keyWords } = this.state;
 const newPageSize = pageSize * (pageIndex || 1);
 let newOptionsData = [],
  len;
 if (data.length > newPageSize) {
  len = newPageSize;
 } else {
  len = data.length;
 }
 if (!!keyWords) {
  let data_ = data.filter(item => item.indexOf(keyWords) > -1) || [];
  data_.forEach((item, index) => {
  if (index < len) {
   newOptionsData.push(item);
  }
  });
 } else {
  data.forEach((item, index) => {
  if (index < len) {
   newOptionsData.push(item);
  }
  });
 }
 this.setState({ optionData: newOptionsData });
 };

 handleScroll = e => {
 e.persist();
 const { target } = e;
 const rmHeight = target.scrollHeight - target.scrollTop;
 const clHeight = target.clientHeight;
 if (rmHeight === 0 && clHeight === 0) {
  this.setState({ scrollPage: 1 });
 } else {
  if (rmHeight < clHeight + 5) {
  console.log(111, rmHeight, clHeight);
  const { scrollPage } = this.state;
  this.setState({ scrollPage: scrollPage + 1 });
  // scrollPage = scrollPage + 1;
  this.loadOption(scrollPage + 1);
  }
 }
 // console.log(e.target)
 };

 render() {
 const { optionData } = this.state;
 console.log(optionData.length);
 return (
  <Select
  showSearch
  allowClear
  onPopupScroll={this.handleScroll}
  style={{ width: 200 }}
  placeholder="Select a person"
  optionFilterProp="children"
  onChange={this.onChange}
  onFocus={this.onFocus}
  onBlur={this.onBlur}
  onSearch={this.onSearch}
  filterOption={(input, option) =>
   option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
  }
  >
  {optionData.map(item => (
   <Option value={item}>{item}</Option>
  ))}
  </Select>
 );
 }
}

ReactDOM.render(<App />, document.getElementById("container"));

其實兩個方法各有優(yōu)劣,第一種的話沒有卡頓,但是展示的數(shù)據(jù)量對于有些人來說可能不太夠,而第二種方法呢雖然下拉沒有卡頓,但是當(dāng)滾動了很多數(shù)據(jù)的時候滾動就會有點卡并且選擇某條數(shù)據(jù)也會有點卡。所以看場景了。

補充知識:VUE element select 選項內(nèi)容顯示過長問題

我就廢話不多說了,大家還是直接看代碼吧~

<style>
 .el-select__tags-text {
 display: inline-block;
 max-width: 120px;
 overflow: hidden;
 text-overflow: ellipsis;
 white-space: nowrap;
 }
 .el-select .el-tag__close.el-icon-close {
 top: -7px;
 }
</style>

以上這篇antd的select下拉框因為數(shù)據(jù)量太大造成卡頓的解決方式就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue3中的reactive函數(shù)聲明數(shù)組方式

    vue3中的reactive函數(shù)聲明數(shù)組方式

    這篇文章主要介紹了vue3中的reactive函數(shù)聲明數(shù)組方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue項目開發(fā)中setTimeout等定時器的管理問題

    vue項目開發(fā)中setTimeout等定時器的管理問題

    這篇文章主要介紹了vue項目開發(fā)中setTimeout等定時器的管理問題,需要的朋友可以參考下
    2018-09-09
  • vue.js 打包時出現(xiàn)空白頁和路徑錯誤問題及解決方法

    vue.js 打包時出現(xiàn)空白頁和路徑錯誤問題及解決方法

    這篇文章主要介紹了vue.js 打包時出現(xiàn)空白頁和路徑錯誤問題及解決方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-06-06
  • Vue.js函數(shù)式組件的全面了解

    Vue.js函數(shù)式組件的全面了解

    函數(shù)式組件就是函數(shù)是組件,組件是函數(shù),它的特征是沒有內(nèi)部狀態(tài)、沒有生命周期鉤子函數(shù)、沒有this(不需要實例化的組件),這篇文章主要給大家介紹了關(guān)于Vue.js函數(shù)式組件的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • vue2滾動條加載更多數(shù)據(jù)實現(xiàn)代碼

    vue2滾動條加載更多數(shù)據(jù)實現(xiàn)代碼

    本篇文章主要介紹了vue2滾動條加載更多數(shù)據(jù)實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-01-01
  • Vue?中v-model的完整用法及原理

    Vue?中v-model的完整用法及原理

    本文主要介紹了Vue?中v-model的完整用法及原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • vue-router實現(xiàn)簡單vue多頁切換、嵌套路由、路由跳轉(zhuǎn)的步驟和報錯

    vue-router實現(xiàn)簡單vue多頁切換、嵌套路由、路由跳轉(zhuǎn)的步驟和報錯

    最近學(xué)習(xí)到VUE路由這塊,發(fā)現(xiàn)這塊知識點有點多,好容易混亂,這篇文章主要介紹了vue-router實現(xiàn)簡單vue多頁切換、嵌套路由、路由跳轉(zhuǎn)的步驟和報錯的相關(guān)資料,需要的朋友可以參考下
    2024-05-05
  • VUE實現(xiàn)吸底按鈕

    VUE實現(xiàn)吸底按鈕

    這篇文章主要為大家詳細(xì)介紹了VUE實現(xiàn)吸底按鈕,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-03-03
  • vite+vue3不清除瀏覽器緩存直接下載最新代碼的解決方案

    vite+vue3不清除瀏覽器緩存直接下載最新代碼的解決方案

    vite+vue3項目發(fā)布后,瀏覽器上還是舊代碼,沒有及時更新到最新代碼,下面通過本文給大家分享vite+vue3不清除瀏覽器緩存直接下載最新代碼的解決方案,感興趣的朋友一起看看吧
    2024-06-06
  • vite+vue3中使用mock模擬數(shù)據(jù)問題

    vite+vue3中使用mock模擬數(shù)據(jù)問題

    這篇文章主要介紹了vite+vue3中使用mock模擬數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評論