1. 效果图
2. 组件完整代码
<template>
<div class="pagination-select">
<el-select
v-model="selectedValue"
:style="{ width: width || '100%' }"
v-bind="attrs"
:remote-method="remoteMethod"
:loading="loading"
@change="val => $emit('change', val)"
@clear="onClear"
@visible-change="val => $emit('visible-change', val)"
:disabled="disabled"
>
<el-option v-for="item in optionSource" :key="item[keyValue]" :label="item[labelKey]" :value="item[valueKey]">el-option>
<el-pagination
small
layout="prev, pager, next"
@current-change="val => pageChange(val)"
:hide-on-single-page="false"
:page-size="paginationOption.pageSize"
:current-page="paginationOption.pageNum"
:pager-count="pagerCount"
:total="paginationOption.total"
>el-pagination>
el-select>
div>
template>
<script>
export default {
name: 'PaginationSelect',
props: {
value: {
type: [String, Number, Object]
},
width: {
type: String
},
loading: {
type: Boolean,
default: false
},
valueKey: {
type: String,
default: ''
},
labelKey: {
type: String,
default: ''
},
keyValue: {
type: String,
default: ''
},
optionSource: {
type: Array,
default: () => []
},
disabled: {
type: Boolean,
default: false
},
pagerCount: {
type: Number,
default: 5
},
paginationOption: {
type: Object,
default: () => {
return {
pageNum: 1,
pageSize: this.$store.state.app.pageSize,
total: 0,
keyword: ''
}
}
}
},
computed: {
selectedValue: {
get() {
return this.value
},
set(val) {
this.$emit('input', val)
}
},
attrs() {
return {
'popper-append-to-body': false,
clearable: true,
filterable: true,
remote: true,
...this.$attrs
}
}
},
watch: {
selectedValue(val) {
this.selectedValue = val
}
},
methods: {
pageChange(val) {
this.$emit('page-change', {
pageNum: val,
pageSize: this.paginationOption.pageSize,
total: this.paginationOption.total,
keyword: this.paginationOption.keyword
})
},
remoteMethod(query) {
this.$emit('remote-method', {
pageNum: 1,
pageSize: this.paginationOption.pageSize,
total: this.paginationOption.total,
keyword: query
})
},
onClear() {
this.$emit('clear')
}
}
}
script>
<style scoped lang="less">
.pagination-select {
::v-deep .el-pagination {
display: flex;
margin-top: 10px;
margin-left: 16px;
background-color: #fff;
align-items: center;
text-align: center;
.el-pager {
display: flex;
align-items: center;
}
}
}
style>
3. 组件使用示例
<el-form-item label="学校" prop="schoolNo">
<PaginationSelect
:loading="schoolLoading"
width="360px"
v-model="ruleForm.schoolNo"
:optionSource="schoolOptions"
labelKey="schoolName"
valueKey="schoolNo"
keyValue="schoolNo"
:paginationOption="schoolPagination"
@page-change="getSchoolList"
@remote-method="getSchoolList"
@visible-change="schoolNoFocus"
@clear="handleClear()"
:loading-text="schoolOptions.length && schoolLoading ? '加载中' : '无数据'"
/>
el-form-item>
data() {
return {
schoolLoading: false,
schoolOptions: [],
schoolPagination: {
pageNum: 1,
pageSize: 10,
total: 0,
keyword: ''
}
}
},
methods: {
init(row) {
this.dialogVisible = true
this.getDetail(row.id)
this.schoolOptions = [
{
schoolNo: row.schoolNo,
schoolName: row.schoolName
}
]
},
getDetail(id) {
getClockEnrollCollectDetail({
clockEnrollCollectId: id
})
.then(res => {
this.ruleForm = res.data.data
})
.catch(err => {})
},
getSchoolList(val) {
this.schoolOptions = []
this.schoolLoading = true
enrollSchoolPage({
pageNum: val.pageNum,
pageSize: val.pageSize,
nameOrNo: val.keyword || ''
})
.then(res => {
this.schoolLoading = false
if (res.data.data.records.length) {
this.schoolOptions = res.data.data.records || []
this.schoolPagination = {
pageNum: val.pageNum,
pageSize: val.pageSize,
keyword: val.keyword || '',
total: res.data.data.total
}
}
})
.catch(err => {
this.schoolLoading = false
})
},
schoolNoFocus(val) {
if (val) {
this.getSchoolList(this.schoolPagination)
} else {
this.schoolPagination.pageNum = 1
this.schoolPagination.keyword = ''
this.schoolPagination.total = 0
}
},
handleClear() {
this.schoolPagination.pageNum = 1
this.schoolPagination.keyword = ''
this.schoolPagination.total = 0
this.ruleForm.schoolNo = ''
this.ruleForm.schoolName = ''
}
}