组件代码:
<template>
<div class="BaseSelect">
<el-select v-option-sroll="loadmore" v-model="inputValue" filterable placeholder="请选择" ref="BaseSelect" @input.native="inputClick" value-key="id">
<el-option v-for="item in dataList" :key="item.id" :label="item.name" :value="item"> </el-option>
</el-select>
</div>
</template>
<script>
import { Debounce } from '@/utils/Debounce.js'
export default {
name: 'BaseSelect',
directives: {
'option-sroll': {
bind(el, binding) {
const SELECTWRAP_DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')
SELECTWRAP_DOM.addEventListener('scroll', function() {
const condition = this.scrollHeight - this.scrollTop <= this.clientHeight
if (condition) {
binding.value()
}
})
}
}
},
data() {
return {
dataList: [], //下拉数据
selectData: '',
inputValue: '',
debounce: Debounce(function() {
//防抖
if (this.isSearch) {
this.filterData(this.$refs.BaseSelect.$data.selectedLabel)
}
}, 1600),
// 数据长度
dropDownDataLength: 0,
// 懒加载长度
loadStart: 0,
loadEnd: 20,
// 监听是否使用了搜索过滤
isSearch: false,
SearchValue: ''
}
},
props: {
// 远程搜索
getDropDownData: {
type: Function,
require: false
},
// 下拉总数据
dropDownData: {
type: Array,
require: true
},
// 搜索过滤条件
filterConditions: {
type: String,
require: false
}
},
created() {},
mounted() {
// this.getDropDownData() //使用组件传入一个过滤函数
},
watch: {
dropDownData(val) {
this.$nextTick(() => {
this.dataList = this.dropDownData.slice(this.loadStart, this.loadEnd)
this.dropDownDataLength = this.dropDownData.length
})
},
SearchValue(val) {
if (val !== '') {
this.isSearch = true
this.debounce()
} else {
this.isSearch = false
this.reset()
}
},
//下拉框的值
inputValue(val) {
this.$emit('selectValue', val)
}
},
methods: {
// 输入框发生改变搜索过滤选项
filterData(value) {
this.dataList = this.dropDownData.filter((item, index) => {
if ((item.name !== null && item.name.indexOf(`${value}`) != -1) || this.inputValue == item.name) {
return true
}
})
},
inputClick(val) {
this.SearchValue = val.target.value // 获取输入框内容
},
// 下拉加载
loadmore() {
this.getUsers(this.formData)
},
getUsers(v) {
if (this.isSearch) {
if (this.loadEnd >= this.dropDownDataLength) {
this.$message({
type: 'info',
message: '下拉选框已加载到底部'
})
return
}
return
}
// 如果还有数据未加载
if (this.loadEnd + 20 <= this.dropDownDataLength) {
this.loadStart += 20
this.loadEnd += 20
} else if (this.loadEnd + 20 > this.dropDownDataLength) {
//无可加载数据
this.loadStart += 20
this.loadEnd += this.dropDownDataLength - this.loadEnd
}
this.dataList = this.dataList.concat(this.dropDownData.slice(this.loadStart, this.loadEnd))
},
// 重置下拉框
reset() {
this.loadStart = 0
this.loadEnd = 20
this.dataList = this.dropDownData.slice(this.loadStart, this.loadEnd)
}
}
}
</script>
使用组件:
//传入下拉数据 选中值返回selectValue事件
<BaseSelect :dropDownData="baseUserList" @selectValue="selectValue"></BaseSelect>
防抖:
export const Debounce = function(fn, delay) {
var timer = null
return function() {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(fn.bind(this), delay) //通过bind改变this指向 指向vue
}
}