el-select如何優化超大數據不卡頓


          <el-form-item
            style="width:100%"
            label="單位"
          >
            <el-select
              v-model="lngcustomerid"
              v-selectloadmore:rangeNum="loadMore(rangeNum)"
              style="width:100%"
              clearable
              filterable
            >
              <el-option
                v-for="item in customerErpList.slice(0,rangeNum)"
                :key="item.lngcustomerid"
                :value="item.lngcustomerid"
                :label="item.strcustomername"
              />
            </el-select>
          </el-form-item>

  

export default{

  directives: {
    'selectloadmore': {
      bind: function(el, binding) {
        // 獲取element-ui定義好的scroll盒子
        const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
        SELECTWRAP_DOM.addEventListener('scroll', function() {
         /** 
                * scrollHeight 獲取元素內容高度(只讀) 
                *scrollTop 獲取或者設置元素的偏移值,常用於, 計算滾動條的位置, 當一個元素的容器沒有產生垂直方向的滾動條, 那它的scrollTop的值默認為0
                *clientHeight 讀取元素的可見高度(只讀)
                *如果元素滾動到底, 下面等式返回true, 沒有則返回false
                *ele.scrollHeight - ele.scrollTop === ele.clientHeight
         */
          const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
          if (condition) binding.value()
        })
      }
    }
  },
data(){
  return{
        lngcustomerid:'',
        customerErpList:[],//假設customerErpList是一個幾千甚至上萬條的數據
        rangeNum: 20 
}  
},
methods:{
   //寫法一
    loadMore(n) {
      // eslint-disable-next-line
      return () => this.rangeNum += 5
    },
   //寫法二
    loadMore(n){
                var self = this
                return function() {
                    self.rangeNum += 5
                    return self.rangeNum
                 }
    },
    //寫法三
     loadMore(n) {
          return () => {
            this.rangeNum += 5
            return this.rangeNum += 5
          }
      },
}
}  

 注:

   以上方法適用於無搜索的情況下,

   如果有搜索要求則存在問題:(1)因為第一次截取的數據是前20條,所以搜索時只能搜這20的數據,之后的搜不到  (2)同樣因為是初次只截取的數據是前20條,所以新增后比如選擇了比較靠后的一條數據保存后,編輯查看時只能顯示id值,而不是label值

所以如果要求搜索建議使用下面的方法

 

方法二:

<el-form-item prop="lngcustomerid" label="供應商">
        <el-select
            v-model="saveInfo.lngcustomerid"
            v-el-select-loadmore:rangeNum="loadMore(rangeNum)"
            style="width: 260px;"
            clearable
            :filter-method="searchTextFunc"
            filterable
            @visible-change="showOptions"
          >
            <el-option
              v-for="item in stashList.slice(0,rangeNum)"
              :key="item.treedataid"
              :value="item.treedataid"
              :label="item.treedatacodeandname"
                />
        </el-select>
 </el-form-item>
export default {
  directives: {
    'el-select-loadmore': {
      bind(el, binding) {
        // 獲取element-ui定義好的scroll盒子
        const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
        SELECTWRAP_DOM.addEventListener('scroll', function() {
          /**
            * scrollHeight 獲取元素內容高度(只讀)
            * scrollTop 獲取或者設置元素的偏移值,常用於, 計算滾動條的位置, 當一個元素的容器沒有產生垂直方向的滾動條, 那它的scrollTop的值默認為0.
            * clientHeight 讀取元素的可見高度(只讀)
            * 如果元素滾動到底, 下面等式返回true, 沒有則返回false:
            * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
            */
          const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
          if (condition) binding.value()
        })
      }
    }
  },
  data() {
    return {
      rangeNum: 20,
      searchText: '',
      stashList: [],
      editSelectId: 0
    }
  },
    computed: {
      ...mapGetters([
        'customerList'
      ])
    },
    mounted() {
      this.$store.dispatch('common/getCustomerList').then(() => {
        this.stashList = this.customerList
      })
    },
  methods: {
    loadMore(n) {
      // eslint-disable-next-line
        return () => this.rangeNum += 5
    },
    searchTextFunc(newVal) {
      if (newVal) {
        this.stashList = this.customerList
        this.stashList = this.stashList.filter(item => {
          if (item.treedatacodeandname.includes(newVal)) {
            return item
          }
        })
      } else {
        this.stashList = this.customerList
      }
    },
    showOptions(v) {
      if (v) {
        this.stashList = this.customerList
        this.searchText = ''
      }
    },
//查看的時候處理數據:循環比較將已經選擇的數據插到stashlist中
examine(){
          if (this.editSelectId) {
              var o = []
              if (this.customerList.some(item => {
                if (item.treedataid === this.editSelectId) {
                  o.push(item)
                  return true
                }
              })) {                
                  this.stashList = this._.unionBy(o, this.stashList, 'treedataid')
              }
            }
    }
  }
}

 

 進階:在方法二的基礎上實現拼音搜索

首先安裝PinyinMatch, 執行 npm install pinyin-match --save

const PinyinMatch = require('pinyin-match')  //拼音搜索插件
export default {
  directives: {
    'el-select-loadmore': {
      bind(el, binding) {
        // 獲取element-ui定義好的scroll盒子
        const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
        SELECTWRAP_DOM.addEventListener('scroll', function() {
          /**
            * scrollHeight 獲取元素內容高度(只讀)
            * scrollTop 獲取或者設置元素的偏移值,常用於, 計算滾動條的位置, 當一個元素的容器沒有產生垂直方向的滾動條, 那它的scrollTop的值默認為0.
            * clientHeight 讀取元素的可見高度(只讀)
            * 如果元素滾動到底, 下面等式返回true, 沒有則返回false:
            * ele.scrollHeight - ele.scrollTop === ele.clientHeight;
            */
          const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
          if (condition) binding.value()
        })
      }
    }
  },
  data() {
    return {
      rangeNum: 20,
      searchText: '',
      stashList: [],
      editSelectId: 0
    }
  },
    computed: {
      ...mapGetters([
        'customerList'
      ])
    },
    mounted() {
      this.$store.dispatch('common/getCustomerList').then(() => {
        this.stashList = this.customerList
      })
    },
  methods: {
    loadMore(n) {
      // eslint-disable-next-line
        return () => this.rangeNum += 5
    },
    searchTextFunc(newVal) {
      if (newVal) {
          //拼音搜索方法
          this.stashList = this.customerList.filter((item) => {
          return PinyinMatch.match(item.treedatacodeandname, newVal)
        })
      } else {
        this.stashList = this.customerList
      }
    },
    showOptions(v) {
      if (v) {
        this.stashList = this.customerList
        this.searchText = ''
      }
    },
    //查看的時候處理數據:循環比較將已經選擇的數據插到stashlist中
    examine(){
          if (this.editSelectId) {
              var o = []
              if (this.customerList.some(item => {
                if (item.treedataid === this.editSelectId) {
                  o.push(item)
                  return true
                }
              })) {                
                  this.stashList = this._.unionBy(o, this.stashList, 'treedataid')
              }
            }
    }
  }
}

 

參考:https://blog.csdn.net/sunnyboysix/article/details/106792693 

pinyinMatch使用參考:https://www.npmjs.com/package/pinyin-match、https://www.cnblogs.com/hellofangfang/p/10906986.html

 
        
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM