<template>
<div class="pagination-select">
<el-default-label-select
v-model="id"
:placeholder="placeholder"
:clearable="clearable"
:filterable="searchable"
:remote="searchable"
:remote-method="remoteMethod"
:loading="remoteLoading"
:disabled="disabled"
:defaultLabel="selectedLabel"
:popper-class="popperClass"
@change="onChange"
@clear="onClear"
style="width: inherit;z-index:9999"
>
<el-option
v-for="(item, index) in dataListFilter"
:key="item[optionValueName]"
:label="item[optionLabelName]"
:value="item[optionValueName]"
:disabled="item.disabled"
>
<slot name="option" :row="item" :$index="index"></slot>
</el-option>
<div style="text-align:center">
<el-pagination
@current-change="pageChange"
:current-page="page"
:page-size="limit"
:total="totalCount"
layout="prev, pager, next"
>
</el-pagination>
</div>
</el-default-label-select>
</div>
</template>
<script>
import ElDefaultLabelSelect from '@/components/el-default-label-select';
import _ from 'lodash';
export default {
components: {
ElDefaultLabelSelect
},
name: 'PaginationSelect',
props: {
value: {
type: [String, Number],
default: null
},
placeholder: {
type: String,
default: '请选择'
},
// 已选中项的label
selectedLabel: {
type: String,
default: ''
},
// 分页条数
limit: {
type: Number,
default: 20
},
// api方法
apiMethod: {
type: Function,
required: true
},
// 是否可远程搜索
searchable: {
type: Boolean,
default: false
},
// 搜索接口字段名称
searchField: {
type: String,
default: 'name'
},
clearable: {
type: Boolean,
default: false
},
disabled: {
type: Boolean,
default: false
},
// 选项值的字段名称
optionValueName: {
type: String,
default: 'id'
},
// 选项label的字段名称
optionLabelName: {
type: String,
default: 'name'
},
popperClass: {
type: String
},
disabledValues: Array
},
data() {
return {
id: this.value,
selectedValue: this.value,
page: 1,
totalCount: 0,
remoteLoading: false,
dataList: [],
keywords: null
};
},
computed: {
dataListFilter() {
let dataList = _.cloneDeep(this.dataList);
if (this.disabledValues && this.disabledValues.length) {
dataList.forEach(item => {
if (this.disabledValues.includes(item[this.optionValueName])) {
item.disabled = true;
} else {
item.disabled = false;
}
});
}
return dataList;
}
},
methods: {
getList() {
this.remoteLoading = true;
let params = {
page: this.page,
limit: this.limit
};
if (this.searchable && this.keywords)
params[this.searchField] = this.keywords;
this.apiMethod(params)
.then(res => {
let dataList = res.data.data.items;
this.dataList = dataList;
this.totalCount = res.data.data.totalCount;
this.remoteLoading = false;
})
.catch(res => {
this.remoteLoading = false;
});
},
reset() {
this.page = 1;
this.getList();
},
remoteMethod(query) {
this.keywords = query;
this.getList();
},
pageChange(page) {
this.page = page;
this.getList();
},
onChange(id) {
let data = this.dataList.find(x => x.id == id);
this.$emit('input', id);
this.$emit('onChange', id, data);
},
onClear() {
this.$emit('onClear');
}
},
watch: {
value(newVal) {
this.id = newVal;
},
id(newVal) {
this.$emit('input', newVal);
}
},
mounted() {
this.getList();
}
};
</script>
<style lang="scss"></style>
# 分页下拉单选组件
用于分页数据的下拉选择
## 基本用法
```javascript
<pagination-single-select
v-model="addForm.collegeMajorId"
:apiMethod="getMajorList"
></pagination-single-select>
远程搜索
指定searchable
即可远程搜索,默认传给接口的搜索的字段是name
<pagination-single-select
v-model="addForm.collegeMajorId"
:apiMethod="getMajorList"
:searchable="true"
></pagination-single-select>
指定远程搜索字段
指定searchField
即远程搜索字段的名称
<pagination-single-select
v-model="addForm.collegeMajorId"
:apiMethod="getMajorList"
:searchable="true"
searchField="fieldName"
></pagination-single-select>
显示已选定的项(编辑回显)
指定selectedLabel
<pagination-single-select
v-model="editForm.collegeMajorId"
:selectedLabel="editForm.collegeMajorName"
:apiMethod="getMajorList"
:searchable="true"
:clearable="true"
style="width:100%"
></pagination-single-select>
⚠️ 注意:用于 el-dialog 组件内且指定了
selectedLabel
用于回显时,因为 el-dialog 关闭默认不销毁元素,会导致回显项实际的值永远是第一次指定的值,所以必须为 el-dialog 设置destroy-on-close
,让 el-dialog 每次在关闭的时候销毁弹窗内的元素。
自定义模板
需指定slot="option"
,slot-scope="scope"
可用于每一个 option 选项的数据回调,如scope.row.name
,另外提供scope.$index
即选项索引可供使用
<pagination-single-select
v-model="editForm.teacherId"
:selectedLabel="editForm.teacherName"
:apiMethod="getTeacherList"
:searchable="true"
searchField="content"
:clearable="true"
style="width:100%"
>
<div slot="option" slot-scope="scope">
<span style="float: left">{{ scope.row.name }}</span>
<span style="float: right; color: #ccc; font-size: 13px">{{
scope.row.departmentName
}}</span>
</div>
</pagination-single-select>
远程搜索接口需要传额外参数的情况
需要对 api 方法做封装之后再传给组件
// 引入api方法
import { getTeacherAndStudentList as getTeacherList } from '@/api/user.js';
// methods中做方法的封装,额外传入固定的type字段
getTeacherListWapper(params) {
return getTeacherList({ ...params, type: 'TEACHER' });
}
// 传入组件
<pagination-single-select
v-model="editForm.teacherId"
:apiMethod="getTeacherListWapper"
>
</pagination-single-select>
Pagenation Single Select Attributes
参数 | 说明 | 类型 | 必选 | 默认值 |
---|---|---|---|---|
value / v-model | 绑定值 | string / number | 是 | - |
apiMethod | API 方法 | function | 是 | - |
placeholder | 占位符 | string | 否 | 请选择 |
selectedLabel | 已选中项的回显 label | string | 否 | - |
limit | 分页条数 | number | 否 | 20 |
searchable | 是否可远程搜索 | boolean | 否 | false |
searchField | 搜索接口字段名称 | string | 否 | name |
clearable | 是否可以清空选项 | boolean | 否 | false |
disabled | 是否禁用 | boolean | 否 | false |
optionValueName | 选项值的字段名称 | string | 否 | id |
optionLabelName | 选项 label 的字段名称 | string | 否 | name |
popper-class | Select 下拉框的类名 | string | 否 | - |
disabledValues | 设为 disabled 的值数组 | array | 否 | - |
Pagenation Single Select Events
事件名称 | 说明 | 回调参数 |
---|---|---|
onChange | 选中值发生变化时触发 | 目前的选中值 |
onClear | 清空选项时触发 | - |
未对 el-select 的其他参数做过多支持,如需支持,在不影响已有实例的使用的情况下,请直接修改组件源码增加可选的 prop 参数即可
引用
getSemesterList(params) {
return getSemesterList({ ...params });
},