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


 
posted @ 2020-09-16 10:00  mark224  阅读(1317)  评论(0编辑  收藏  举报