el-select 组件 懒加载 可远程搜索

用于分页数据的懒加载 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.clientHeight
						if (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 | value
			isConcat: {
				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: '全部'
			},
			// 加载loading
			loading: {
				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 = val
							this.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.value
				if (val==='null' || val===null || val==='undefined' || val===undefined || val===''){
					this.clearChange()
				}
			  },
			  immediate: false,
			  deep: true
			}
		},
		mounted() {
			 this.defaultValue = this.value
			this.optionsList = this.options
		},
		methods: {
			//选择后 只显示label
			//张三
			concatString(a, b) {
				a = a || ''
				b = b || ''
				if (this.isConcat) {
					// return a + ((a && b) ? ' | ' : '') + b
					return 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) ? ' | ' : '') + b
					if (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 = false
						this.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 = 1
				if (this.timer) {
					clearTimeout(this.timer)
					this.timer = null
				}
				this.timer = setTimeout(() => {
					this.isRemote = true
					this.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=this
				that.projectPageNum =page
			    this.projectSearch('',true)
			},
			//项目号 下拉框的远程搜索
			remoteMethod(query, page) {
			  this.projectPageNum = page
			    this.projectSearch(query,false)
			},
			/**项目号搜索 列表展示*/
			projectSearch(val, lazy = false) {
				let that = this
				if (lazy == false) { // 如果不是懒加载,
					this.projectList = [] // 把select选项数组重置为空
					that.projectPageNum = 1 // 设置查询第一页,每页20条
				}
				//请求后台数据
				listInfo({
					search: val,
					pageSize: 30,
					pageNum: that.projectPageNum
				}).then(response => {
					that.projectList=response.rows
				});
			},
}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
el-select 组件Vue.js 中是一个下拉选择器组件,而 "懒加载" 是一种优化技术,用于在需要时再加载数据,以减少初始加载时间和资源消耗。 如果你想要实现 el-select 组件懒加载,你可以使用其提供的远程搜索功能。该功能允许你在用户输入时动态加载选项。 以下是一个简单的示例代码,演示了如何使用 el-select懒加载功能: ```vue <template> <el-select v-model="selectedOption" filterable remote :remote-method="loadOptions" > <el-option v-for="option in options" :key="option.value" :label="option.label" :value="option.value" ></el-option> </el-select> </template> <script> export default { data() { return { selectedOption: '', options: [] }; }, methods: { loadOptions(query) { // 在这里根据输入的 query 加载远程数据 // 例如使用 axios 发起异步请求获取数据 axios.get('/api/options', { params: { query } }) .then(response => { this.options = response.data; }) .catch(error => { console.error(error); }); } } }; </script> ``` 在上面的代码中: - `v-model` 绑定了选中的选项的值; - `filterable` 启用了可搜索功能,允许用户输入查询条件; - `remote` 启用了远程搜索功能; - `remote-method` 指定了一个方法名,用于在用户输入时触发加载选项的远程数据。 你需要替换示例代码中的 `/api/options` 为实际的后端接口地址,以便获取远程数据。这个接口应该根据输入的查询条件返回相应的选项数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值