用于分页数据的懒加载 vue+elment
新建elSelct.vue 组件
<template><div><el-select v-el-select-loadmore="loadMore" :value="defaultValue" :loading="loading" :multiple="multiple":placeholder="placeholder" :allow-create="allowCreate" filterable remote clearable:remote-method="(query) => {remoteMethod(query, value)}" style="width: 100%;" @change="change"@input="$emit('input',$event)" @visible-change="visibleChange" @clear="clearChange"><el-option v-if="hasAll" :label="defaultLabel" value="" /><el-option v-for="(item,index) in optionsList" :key="item.index+'s'+item.id":label="concatString2(item[label], item[labelTwo])" :value="item[valueString]">{{ concatString(item[label], item[labelTwo]) }}</el-option></el-select></div>
</template><script>export default {name: 'YSelect',directives: {'el-select-loadmore': {bind(el, binding) {// 获取element-ui定义好的scroll盒子const DOM = el.querySelector('.el-select-dropdown .el-select-dropdown__wrap')DOM.addEventListener('scroll', function() {/*** scrollHeight 获取元素内容高度(只读)* scrollTop 获取或者设置元素的偏移值,常用于, 计算滚动条的位置, 当一个元素的容器没有产生垂直方向的滚动条, 那它的scrollTop的值默认为0.* clientHeight 读取元素的可见高度(只读)* 如果元素滚动到底, 下面等式返回true, 没有则返回false:* ele.scrollHeight - ele.scrollTop === ele.clientHeight;*/const condition = this.scrollHeight - this.scrollTop <= this.clientHeightif (condition) {binding.value()}})}}},props: {// 是否允许创建条目allowCreate: {type: Boolean,default: false},// 需要显示的名称label: {type: String,default: ''},// 需要显示的名称labelTwo: {type: String,default: ''},// 传入的数据,必填value: {type: [String, Number, Array],default: null},// 是否拼接label | valueisConcat: {type: Boolean,default: false},isConcatShowText: {type: Boolean,default: false},// 拼接label、value符号concatSymbol: {type: String,default: ' | '},valueString: {type: String,default: ''},// 选项数据,必填options: {type: Array,default: () => {return []}},// 是否有全部选项hasAll: {type: Boolean,default: true},defaultLabel: {type: String,default: '全部'},// 加载loadingloading: {type: Boolean,default: false},// 提示placeholder: {type: String,default: '请选择'},// 是否支持多选multiple: {type: Boolean,default: false},// 每次显示数量size: {type: Number,default: 100}},data() {return {page: 1,pageRemote: 1,defaultLoading: false,timer: null,optionsList: [],oldOptions: [],isRemote: false,defaultValue:null,}},watch: {options: {handler(val) {if (this.isRemote) {if (val) {this.optionsList = valthis.oldOptions = this.oldOptions.filter((item) => {return !val.some(valItem => item.id === valItem.id)})this.oldOptions = [...this.oldOptions, ...val]}} else {if (val) {this.optionsList = this.optionsList.filter((item) => {return !val.some(valItem => item.id === valItem.id)})this.optionsList = [...this.optionsList, ...val]}}},deep: true},value: {handler(val, oldVal) {this.defaultValue = this.valueif (val==='null' || val===null || val==='undefined' || val===undefined || val===''){this.clearChange()}},immediate: false,deep: true}},mounted() {this.defaultValue = this.valuethis.optionsList = this.options},methods: {//选择后 只显示label//张三concatString(a, b) {a = a || ''b = b || ''if (this.isConcat) {// return a + ((a && b) ? ' | ' : '') + breturn a + ((a && b) ? this.concatSymbol : '') + b}return a},//选择下拉展示时 可以展示label和labelTwo//123||张三concatString2(a, b) {a = a || ''b = b || ''if (this.isConcat) {// return a + ((a && b) ? ' | ' : '') + bif (this.isConcatShowText == true) {return a + ((a && b) ? this.concatSymbol : '') + b} else {return a}}return a},change(val) {console.log('change', val)this.$emit('change', val)},visibleChange(status) {console.log('change2', status)if (!status) {if (this.isRemote) {this.isRemote = falsethis.optionsList = [...this.oldOptions]}}this.$emit('visibleChange', status)},loadMore() {console.log(this.isRemote, this.pageRemote, this.page)if (this.isRemote) {if (this.pageRemote === 1) {this.$emit('loadMore', this.pageRemote)this.pageRemote++} else {this.pageRemote++this.$emit('loadMore', this.pageRemote)}} else {this.page++this.$emit('loadMore', this.page)}},remoteMethod(query) {this.pageRemote = 1if (this.timer) {clearTimeout(this.timer)this.timer = null}this.timer = setTimeout(() => {this.isRemote = truethis.oldOptions = [...this.optionsList]this.optionsList = []this.$emit('remoteMethod', query, this.pageRemote)}, 500)},//清除clearChange() {if (typeof this.defaultValue === 'string') {this.defaultValue = ''} else if (this.isMultiple) {this.defaultValue = []}this.$emit('clear')}}}
</script><style lang='scss' scoped></style>
然后再页面引用
hasAll 是否显示全部2个字 is-concat 是否拼接 concat-symbol拼接符号 is-multiple是否多选 label 字段名称1 labelTwo 字段名称2 valueString要获取的value值,是id还是projectCode options显示的数据 @loadMore加载更多 的方法 @remoteMethod远程请求的方法 @change方法
[{name:'我是名称’,projectCode:‘0121’,id:1}]
<template><YSelect v-model="form.contractNumber" :hasAll='false' :is-concat="true" :is-multiple="false":isConcatShowText="false" :concat-symbol="' || '" label="name" labelTwo="projectCode" valueString="id" :options="contractList" :placeholder="'请选择合同编号'" @loadMore="loadMore" @remoteMethod="remoteMethod" @change="selectContract" @clear='contractClear()'/>
</template>import YSelect from '@/views/components/elSelect/index'
export default {
components: {YSelect},
data:{return(){projectPageNum:0}
},
mounted() {
this.projectSearch()
},
methods: {
//清除
contractClear(){},
//下拉框选中完成后visibleChange(status) {},//下拉框改变时selectChange(){},//项目号 懒加载 下拉加载更多loadMore(page) {let that=thisthat.projectPageNum =pagethis.projectSearch('',true)},//项目号 下拉框的远程搜索remoteMethod(query, page) {this.projectPageNum = pagethis.projectSearch(query,false)},/**项目号搜索 列表展示*/projectSearch(val, lazy = false) {let that = thisif (lazy == false) { // 如果不是懒加载,this.projectList = [] // 把select选项数组重置为空that.projectPageNum = 1 // 设置查询第一页,每页20条}//请求后台数据listInfo({search: val,pageSize: 30,pageNum: that.projectPageNum}).then(response => {that.projectList=response.rows});},
}
}