vue3 elementPlus select选择器下拉加载更多
element
A Vue.js 2.0 UI Toolkit for Web
项目地址:https://gitcode.com/gh_mirrors/eleme/element
免费下载资源
·
选择器下拉实现分页加载
1、使用Infinite Scroll 无限滚动 v-infinite-scroll
selectLoadMore.vue
<template>
<el-select
style="width: 100%"
v-if="isMounted"
v-model="_modelValue"
remote
reserve-keyword
@visible-change="handleVisibleChange"
@change="handelChange"
:remote-method="remoteMethod"
filterable
:loading="loading"
clearable
:multiple="multiple"
:disabled="disabled"
:placeholder="placeholder">
<div
v-infinite-scroll="loadMore"
:infinite-scroll-delay="500"
style="overflow-y: hidden">
<el-option
v-for="item in optionsList"
:key="item[optionName.value]"
:label="item[optionName.label]"
:value="item[optionName.value]" />
</div>
</el-select>
</template>
<script setup>
const { proxy } = getCurrentInstance();
//selectLoadMoreDefault 为分页参数
const { selectLoadMoreDefault } = proxy.constants;
const props = defineProps({
options: {
type: Array
},
modelValue: {
type: [String, Number]
},
optionsName: {
type: Object,
default: () => ({})
},
total: {
type: Number,
default: 0
},
pageSize: {
type: Number,
default: 0
},
pageNum: {
type: Number,
default: 0
},
getList: {
type: Function
},
placeholder: {
type: String,
default: '请输入/选择'
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
// 除分页参数的其他参数
otherParams: {
type: Object,
default: () => ({})
}
});
const emits = defineEmits(['changeData', 'update:modelValue']);
const pageSize = computed(
() => props.pageSize || selectLoadMoreDefault.pageSize
);
const pageNum = computed(() => props.pageNum || selectLoadMoreDefault.pageNum);
const queryParams = ref({
pageSize: pageSize.value,
pageNum: pageNum.value,
name: ''
});
const visible = ref(false);
const _modelValue = ref(props.modelValue);
watch(
() => [props.modelValue, props.total],
(val) => {
_modelValue.value = val[0];
emits('update:modelValue', val[0]);
if (!val[1]) {
queryParams.value.pageNum = 1;
}
}
);
const loading = ref(false);
const isMounted = ref(false);
const optionsList = computed(() => props.options);
onMounted(() => {
isMounted.value = true;
});
// 下拉选属性配置
const optionName = computed(() => {
return {
label: props.optionsName?.label ?? 'label',
value: props.optionsName?.value ?? 'value'
};
});
const handelChange = (val) => {
emits('changeData', val);
emits('update:modelValue', val);
};
const loadMore = () => {
let sum = queryParams.value.pageNum * queryParams.value.pageSize;
if (sum >= props.total) return;
visible.value && remoteMethod(queryParams.value.name, false);
};
const remoteMethod = (query, isEmpty = true) => {
// debugger;
if (visible.value) {
queryParams.value.name = query;
// if (query || !isEmpty) {
queryParams.value.pageNum = isEmpty ? 1 : queryParams.value.pageNum + 1;
// loading.value = true;
setTimeout(() => {
// loading.value = false;
props.getList({ ...queryParams.value, ...props.otherParams }, isEmpty);
}, 200);
// }
}
};
// 控制下拉框的显示隐藏
const handleVisibleChange = (isVisible) => {
visible.value = isVisible;
};
</script>
2、自定义指令(推荐)
<template>
<!--
popper-class="single-select-loadmore" -->
<el-select
style="width: 100%"
v-if="isMounted"
v-model="_modelValue"
remote
reserve-keyword
@visible-change="handleVisibleChange"
@change="handelChange"
:remote-method="remoteMethod"
filterable
:loading="loading"
clearable
v-loadMore="loadMore"
:multiple="multiple"
:disabled="disabled"
:placeholder="placeholder"
:teleported="false">
<el-option
v-for="item in optionsList"
:key="item[optionName.value]"
:label="item[optionName.label]"
:value="item[optionName.value]" />
</el-select>
</template>
<script setup>
const { proxy } = getCurrentInstance();
const { selectLoadMoreDefault } = proxy.constants;
const props = defineProps({
options: {
type: Array
},
modelValue: {
type: [String, Number]
},
optionsName: {
type: Object,
default: () => ({})
},
total: {
type: Number,
default: 0
},
pageSize: {
type: Number,
default: 0
},
pageNum: {
type: Number,
default: 0
},
getList: {
type: Function
},
placeholder: {
type: String,
default: '请输入/选择'
},
disabled: {
type: Boolean,
default: false
},
multiple: {
type: Boolean,
default: false
},
clearable: {
type: Boolean,
default: true
},
// 除分页参数的其他参数
otherParams: {
type: Object,
default: () => ({})
}
});
const emits = defineEmits(['changeData', 'update:modelValue']);
const pageSize = computed(
() => props.pageSize || selectLoadMoreDefault.pageSize
);
const pageNum = computed(() => props.pageNum || selectLoadMoreDefault.pageNum);
const queryParams = ref({
pageSize: pageSize.value,
pageNum: pageNum.value,
name: ''
});
const visible = ref(false);
const _modelValue = ref(props.modelValue);
watch(
() => [props.modelValue, props.total],
(val) => {
_modelValue.value = val[0];
emits('update:modelValue', val[0]);
if (!val[1]) {
queryParams.value.pageNum = 1;
}
}
);
const loading = ref(false);
const isMounted = ref(false);
const optionsList = computed(() => props.options);
onMounted(() => {
isMounted.value = true;
});
onUnmounted(() => {
isMounted.value = false;
});
// 下拉选属性配置
const optionName = computed(() => {
return {
label: props.optionsName?.label ?? 'label',
value: props.optionsName?.value ?? 'value'
};
});
const handelChange = (val) => {
emits('changeData', val);
emits('update:modelValue', val);
};
const loadMore = () => {
// debugger;
let sum = queryParams.value.pageNum * queryParams.value.pageSize;
if (sum >= props.total) return;
visible.value && remoteMethod(queryParams.value.name, false);
};
const remoteMethod = (query, isEmpty = true) => {
// debugger;
if (visible.value) {
queryParams.value.name = query;
// if (query || !isEmpty) {
queryParams.value.pageNum = isEmpty ? 1 : queryParams.value.pageNum + 1;
// loading.value = true;
setTimeout(() => {
// loading.value = false;
props.getList({ ...queryParams.value, ...props.otherParams }, isEmpty);
}, 200);
// }
}
};
// 控制下拉框的显示隐藏
const handleVisibleChange = (isVisible) => {
visible.value = isVisible;
};
</script>
loadmore.js
import { nextTick } from 'vue';
const Loadmore = {
mounted(el, binding) {
nextTick(() => {
// teleported为true 需添加popper-class .single-select-loadmore
const domClass = '.el-select-dropdown__wrap';
const element = el.querySelector(domClass);
let handleScroll = () => {
const { scrollTop, scrollHeight, clientHeight } = element;
const scrollDistance = scrollHeight - scrollTop <= clientHeight;
if (scrollDistance) {
binding.value(); // 调用加载更多的回调函数
}
};
// 将事件处理函数存储在元素的某个属性上以便后续引用
element.__vueCustomEvent__ = handleScroll;
// 监听滚动事件
element && element.addEventListener('scroll', handleScroll);
});
},
beforeUnmount(el) {
// 从元素上获取滚动事件并移除监听器
const domClass = '.el-select-dropdown__wrap';
const element = el.querySelector(domClass);
if (element.__vueCustomEvent__) {
element.removeEventListener('scroll', element.__vueCustomEvent__);
// 可选:删除存储的函数引用以避免内存泄漏
delete element.__vueCustomEvent__;
}
}
};
export default Loadmore;
使用
<select-loadmore
v-model="form.id"
:get-list="handlesSelect"
placeholder="请输入/选择"
@change-data="changeAddMember"
:other-params="{
// deptId: quest_deptId,
}"
:options="drugList"
:options-name="{ label: 'text', value: 'drugId' }"
:total="drugTotal" />
const handlesSelectDrug = (query, isEmpty) => {
let newQuery = JSON.parse(JSON.stringify(query));
if (newQuery.isEmpty) {
delete newQuery.isEmpty;
}
if (newQuery.name) {
newQuery.chemicalName = newQuery.name;
delete newQuery.name;
}
listDrug(newQuery).then((response) => {
let list = response.rows;
list.value = isEmpty
? response.rows
: [...list.value, ...response.rows];
total.value = response.total;
});
};
handlesSelectDrug({ ...selectLoadMoreDefault }, false);
GitHub 加速计划 / eleme / element
10
1
下载
A Vue.js 2.0 UI Toolkit for Web
最近提交(Master分支:5 个月前 )
c345bb45
9 个月前
a07f3a59
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update transition.md
* Update table.md
* Update table.md
* Update transition.md
* Update popover.md 9 个月前
更多推荐
已为社区贡献3条内容
所有评论(0)