针对我们项目中经常会遇到下拉框在遇到大量数据时,加载会卡顿,用户体验感不好。针对该情况我对el-select组件做了一下修改,来满足这样大量数据下拉不卡顿。提高用户的体验感。
具体代码如下:
<template> <div> <el-select style="width: 100%" v-model="selectValue" :placeholder="selectProps.placeholder || '请选择'" size="mini" filterable :filter-method="delayFilter" @change="selectChange" v-selectloadmore="loadMore" > <el-option v-for="(item, index) in options" :key="item[selectProps.value || 'value'] + index" :label="item[selectProps.label || 'label']" :value="item[selectProps.value || 'value']" ></el-option> </el-select> </div> </template> <script> import _ from 'lodash' export default { name: 'large-data-select', directives: { 'selectloadmore': { 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 - 2 <= this.clientHeight if (condition) { binding.value() } }) } } }, props: { selectProps: { type: Object, default: () => { return { options: [], rangeNumber: 50 } }, require: true }, dataIndex: { type: Number, default: 0 }, value: { type: String, default: '' } }, data () { return { selectValue: '', rangeNumber: this.selectProps.rangeNumber || 50, options: [], originalData: [], query: '' } }, watch: { value: { handler (newVal) { this.selectValue = newVal }, deep: true, immediate: true }, selectProps () { this.init() } }, created () { this.delayFilter = _.debounce((query) => { this.filter(query) }, 500) }, mounted () { this.$nextTick(() => { if (this.selectProps.options && this.selectProps.options.length > 0) { this.init() } }) }, methods: { init () { this.originalData = this.selectProps.options.concat() this.initRenderOpions(this.originalData) }, loadMore (n) { if (n < 8) this.rangeNumber = 10 this.rangeNumber += 5 // 每次滚动到底部可以新增条数 可自定义 this.filter(this.query) }, filter (query) { this.query = query if (this.query) { const newOption = this.originalData.filter((item) => item[this.selectProps.label || 'label'].includes(query) ) this.initRenderOpions(newOption) } else { this.initRenderOpions(this.originalData) } }, selectChange () { this.$emit('updateChange', this.selectValue, this.dataIndex) this.initRenderOpions(this.originalData) }, initRenderOpions (list) { const options = list.slice(0, this.rangeNumber) let index = -1 if (_.size(this.selectValue)) { index = _.findIndex(options, (item) => { return item[this.selectProps.label || 'label'] === this.selectValue }) if (index === -1) { const currentItem = _.find(list, (game) => { return game[this.selectProps.label || 'label'] === this.selectValue }) if (currentItem) { options.unshift(currentItem) } } } this.options = options } } } </script>
标签:selectProps,originalData,selectValue,elment,label,修改,组件,query,options From: https://www.cnblogs.com/llwang43/p/18060802