赞
踩
当我们的下拉列表数据量过大时,初始化可能会有卡顿现象,我们可以通过滚动显示更多数据来解决这个问题。
// 控件名称 LargeDataSearchSelect <tempalte> <div></div> </tempalte> <script> export default { name: 'large-data-search-select', 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() }) } } }, props: { selectProps: { type: Object, default: () => { return { options: [], rangeNumber: 100 } }, require: true }, value: { type: String, default: '' } }, data() { return { selectValue: '', rangeNumber: this.selectProps.rangeNumber || 100, options: [], originalData: [] } }, 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(() => { this.init() }) }, methods: { init() { this.originalData = this.selectProps.options this.initRenderOpions() }, loadMore(n) { if (n < 8) this.rangeNumber = 10 return () => (this.rangeNumber += 5) // 每次滚动到底部可以新增条数 可自定义 }, filter(query) { if (query) { let newOption = this.originalData.filter((item) => item[this.selectProps.label || 'label'].includes(query) ) if(newOption.length) { return this.options = newOption } } this.initRenderOpions() }, selectChange() { this.$emit('updateChange', this.selectValue) this.initRenderOpions() }, initRenderOpions() { let options = this.originalData.slice(0, this.rangeNumber) let index = -1 if (_.size(this.selectValue)) { index = _.findIndex(options, (item)=>{ return item.game_id === this.selectValue }) if(index === -1) { let currentItem = _.find(this.originalData, (game)=>{ return game.game_id === this.selectValue }) if(currentItem) { options.unshift(currentItem) } } } this.options = options } }, render() { return ( <el-select {...this.$attrs} v-model={this.selectValue} placeholder={this.selectProps.placeholder || '请选择'} popper-append-to-body={false} clearable filterable filter-method={this.delayFilter} onChange={this.selectChange} v-el-select-loadmore:rangeNumber={this.loadMore(this.rangeNumber)} > {this.options.map((item, index) => { return ( <el-option key={item[this.selectProps.value || 'value']} label={item[this.selectProps.label || 'label']} value={item[this.selectProps.value || 'value']} ></el-option> ) })} </el-select> ) } } </script>
<template> <!-- 原本的 el-select --> <!-- <el-select class="extern-header-gamelist fl" size="small" v-model="gameId" filterable placeholder="请按游戏筛选查看"--> <!-- @change="onChangeGameIdHandler">--> <!-- <el-option v-for="(item, index) in gameList" :label="item.game_name" :value="item.game_id" :key="index"--> <!-- style="width:217px;"></el-option>--> <!-- </el-select>--> <!-- 使用自己封装的el-select --> <LargeDataSearchSelect class="extern-header-gamelist fl" size="small" v-model="gameId" :selectProps.sync="selectProps" @updateChange="onChangeGameIdHandler" /> </template> <script> import util from '@/common/util' import LargeDataSearchSelect from "@/components/large-data-search-select"; export default { name: "app", components: { LargeDataSearchSelect }, data(){ return { gameList: [], gameId: util.getGameId(), } }, computed: { selectProps() { return { placeholder: '请按游戏筛选查看', options: _.clone(this.gameList), rangeNumber: 100, label: "game_name", value: "game_id" } }, }, created() { this.fetchGameList() }, methods: { async fetchGameList() { let result; result = await IBOX.waxios({ url: `${IBOX.config.baseURL}api/get_gs_games`, method: 'Get' }) if(result && result.ret === 0 && _.isArray(result.data)) { this.gameList = _.map(result.data, (game) => { return { game_id: '' + game.game_id, game_name: `[${game.game_id}]${game.game_name}` } }) IBOX.gameList = this.gameList; this.selectProps.options = _.clone(this.gameList); this.$store.commit('updateGameList', this.gameList) }else{ this.$alert(staticData.requestFailMessage).then(()=>{ this.fetchGameList() }) } }, onChangeGameIdHandler(gameId) { if(util.getGameId() !== gameId) { util.setGameId(gameId); this.$emit('change-game'); } }, } } </script>
原文转载来自: 解决el-select数据量过大卡顿问题-记录贴
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。