用于分頁數據的懶加載 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});},
}
}