封装el-select滚动底部加载更多
vue2 实现el-select 下拉列表滚动加载更多数据
父组件页面使用
<template>
<LoadMoreSelect
v-model="selectValue"
:fetchOptions="fetchStockLocationData"
keyField="Cid"
labelField="Code"
valueField="Cid"
:initialPage="initialPage"
:pageSize="pageSize"
/>
</template>
<script>
import LoadMoreSelect from "../components/LoadMoreSelect/index.vue";
import { mapActions } from "vuex";
export default {
name: "LoadMore",
components: {
LoadMoreSelect,
},
data() {
return {
selectValue: null,
initialPage: 1,
pageSize: 15,
};
},
methods: {
...mapActions({
getStockLocationDataAction: "stock/getStockLocationDataAction",
}),
async fetchStockLocationData({ page, pageSize }) {
const response = await this.getStockLocationDataAction({
page_no: page,
page_size: pageSize,
all: false,
detail: false,
});
return response;
},
},
};
</script>
子组件主要代码 components/LoadMoreSelect/index.vue
<template>
<el-select
:placeholder="placeholder"
v-model="internalValue"
@change="handleChange"
size="mini"
clearable
>
<el-option
v-for="item in options"
:key="item[keyField]"
:label="item[labelField]"
:value="item[valueField]"
>
<span style="float: left; font-size: 12px">{{ item.Code }}</span>
<span
style="float: right; color: #8492a6; font-size: 12px; margin-left: 5px"
>{{ item.Description }}</span
>
</el-option>
<ElSelectLoading
:page="currentPage"
:loading="loading"
:hasMore="hasMore"
@loadMore="handleLoadMore"
/>
</el-select>
</template>
<script>
import ElSelectLoading from "./ElSelectLoading.vue";
export default {
components: {
ElSelectLoading,
},
props: {
//选中值
value: {
type: [String, Number],
default: null,
},
placeholder: {
type: String,
default: "please select",
},
//异步请求
fetchOptions: {
type: Function,
required: true,
},
keyField: {
type: String,
default: "id",
},
labelField: {
type: String,
default: "name",
},
valueField: {
type: String,
default: "id",
},
initialPage: {
type: Number,
default: 1,
},
pageSize: {
type: Number,
default: 10,
},
},
data() {
return {
internalValue: this.value,
options: [],
loading: false,
hasMore: true,
currentPage: this.initialPage,
};
},
watch: {
value(newVal) {
this.internalValue = newVal;
},
internalValue(newVal) {
this.$emit("input", newVal);
},
},
mounted() {
this.loadOptions(this.currentPage, this.pageSize);
},
methods: {
async loadOptions(page, pageSize) {
if (this.loading) return;
this.loading = true;
try {
const res = await this.fetchOptions({ page, pageSize });
const list = res.data.list || [];
if (page === this.initialPage) {
this.options = [];
}
this.options.push(...list);
this.hasMore = this.options.length < res.data.total;
this.currentPage = page;
} catch (error) {
console.error(error);
} finally {
this.loading = false;
}
},
handleLoadMore() {
this.loadOptions(this.currentPage + 1, this.pageSize);
},
handleChange(value) {
this.internalValue = value;
this.$emit("change", value);
},
},
};
</script>
<style scoped lang="scss"></style>
底部的加载状态 ./ElSelectLoading.vue
<template>
<el-select
:placeholder="placeholder"
v-model="internalValue"
@change="handleChange"
size="mini"
clearable
>
<el-option
v-for="item in options"
:key="item[keyField]"
:label="item[labelField]"
:value="item[valueField]"
>
<span style="float: left; font-size: 12px">{{ item.Code }}</span>
<span
style="float: right; color: #8492a6; font-size: 12px; margin-left: 5px"
>{{ item.Description }}</span
>
</el-option>
<ElSelectLoading
:page="currentPage"
:loading="loading"
:hasMore="hasMore"
@loadMore="handleLoadMore"
/>
</el-select>
</template>
<script>
import ElSelectLoading from "./ElSelectLoading.vue";
export default {
components: {
ElSelectLoading,
},
props: {
//选中值
value: {
type: [String, Number],
default: null,
},
placeholder: {
type: String,
default: "please select",
},
//异步请求
fetchOptions: {
type: Function,
required: true,
},
keyField: {
type: String,
default: "id",
},
labelField: {
type: String,
default: "name",
},
valueField: {
type: String,
default: "id",
},
initialPage: {
type: Number,
default: 1,
},
pageSize: {
type: Number,
default: 10,
},
},
data() {
return {
internalValue: this.value,
options: [],
loading: false,
hasMore: true,
currentPage: this.initialPage,
};
},
watch: {
value(newVal) {
this.internalValue = newVal;
},
internalValue(newVal) {
this.$emit("input", newVal);
},
},
mounted() {
this.loadOptions(this.currentPage, this.pageSize);
},
methods: {
async loadOptions(page, pageSize) {
if (this.loading) return;
this.loading = true;
try {
const res = await this.fetchOptions({ page, pageSize });
const list = res.data.list || [];
if (page === this.initialPage) {
this.options = [];
}
this.options.push(...list);
this.hasMore = this.options.length < res.data.total;
this.currentPage = page;
} catch (error) {
console.error(error);
} finally {
this.loading = false;
}
},
handleLoadMore() {
this.loadOptions(this.currentPage + 1, this.pageSize);
},
handleChange(value) {
this.internalValue = value;
this.$emit("change", value);
},
},
};
</script>
标签:el,封装,String,pageSize,default,value,type,page,select
From: https://blog.csdn.net/qq_52132550/article/details/139543754