element ui 分页组件

233 阅读1分钟
<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-
apiMethodAPI 方法function-
placeholder占位符string请选择
selectedLabel已选中项的回显 labelstring-
limit分页条数number20
searchable是否可远程搜索booleanfalse
searchField搜索接口字段名称stringname
clearable是否可以清空选项booleanfalse
disabled是否禁用booleanfalse
optionValueName选项值的字段名称stringid
optionLabelName选项 label 的字段名称stringname
popper-classSelect 下拉框的类名string-
disabledValues设为 disabled 的值数组array-

Pagenation Single Select Events

事件名称说明回调参数
onChange选中值发生变化时触发目前的选中值
onClear清空选项时触发-

未对 el-select 的其他参数做过多支持,如需支持,在不影响已有实例的使用的情况下,请直接修改组件源码增加可选的 prop 参数即可

引用

                                    getSemesterList(params) {
		return getSemesterList({ ...params });
	},