一、代码实现
1. 单个下拉框
<template>
<div>
<!-- 为了启用远程搜索,需要将filterable和remote设置为true,同时传入一个remote-method。
remote-method为一个Function,它会在输入值发生变化时调用,参数为当前输入值。需要注意的是,
如果el-option是通过v-for指令渲染出来的,此时需要为el-option添加key属性,且其值需具有唯一性,比如此例中的cell.userId -->
<el-select v-model="obj" value-key="userId" :placeholder="userName ? userName : '请选择'" filterable :remote-method="getData" remote
@change="change($event)" style="width: 100%">
<el-option v-for="cell in dataList" :key="cell.userId" :label="(cell.nickName + '(' + cell.deptName + ')')"
:value="cell">
</el-option>
<div class="pagination-css">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="pageNum"
:page-sizes="[2, 5, 10, 15]" :page-size="pageSize" layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
</el-select>
</div>
</template>
<script>
export default {
name: "pageSelect",
data() {
return {
obj: {},
userName: '',
// 数据
dataList: [
{
userId: 1,
nickName: '张三',
deptId: 1,
deptName: '测试1'
},
{
userId: 2,
nickName: '李四',
deptId: 2,
deptName: '测试2'
},
{
userId: 3,
nickName: '王五',
deptId: 3,
deptName: '测试3'
},
{
userId: 4,
nickName: '赵六',
deptId: 4,
deptName: '测试4'
}, {
userId: 5,
nickName: '小米',
deptId: 5,
deptName: '测试5'
},
{
userId: 6,
nickName: '小明',
deptId: 6,
deptName: '测试6'
},
{
userId: 7,
nickName: '小张',
deptId: 7,
deptName: '测试7'
},
],
pageNum: 1,
pageSize: 10,
total: 7,
search:'',
};
},
methods: {
//获取数据(远程搜索)
getData(search){
console.log(search,'search')
if (typeof search == "string") {
this.search = search;
}
// 根据实际项目调用
// getList({
// pageNum: this.pageNum,
// pageSize: this.pageSize,
// nickName: this.search,
// }).then((response) => {
// this.dataList = response.rows;
// this.total = response.total;
// });
},
//选择
change(event) {
console.log(event,'event')
// 如果有多个下拉框,需要判断数据不重复选择,可以获取选中的数据列表的唯一值组成的数组
// 然后判断唯一值有没有重复(数组去重,判断前后数组长度是否变化),有则是提示不能重复选择。
},
// 分页相关
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
this.pageSize = val;
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
this.pageNum = val;
},
},
};
</script>
<style>
.pagination-css {
width: 100%;
display: flex;
justify-content: flex-end;
}
</style>
2. 多个下拉框
<template>
<div class="person-box">
<div class="add-css">
<el-button size="mini" type="success" plain @click="add">
添加
</el-button>
</div>
<el-form ref="form" :inline="false" :model="form" :rules="rules" label-position="right" label-suffix=":"
label-width="120px">
<div class="person-list">
<div class="person-item" v-for="(item, index) in form.list" :key="item.id">
<div class="num-box">{{ index + 1 }}.</div>
<el-row :gutter="20" type="flex">
<el-col :span="20">
<el-form-item label="" :prop="`list.${index}.personObj`" :rules="rules.personObj">
<el-select v-model="item.personObj" value-key="userId"
:placeholder="item.userName ? item.userName : '请选择'" filterable
:remote-method="getPersonList" remote @change="personChange($event, item)"
style="width: 100%">
<el-option v-for="cell in personData" :key="cell.userId"
:label="cell.nickName + '(' + cell.deptName + ')'" :value="cell">
</el-option>
<div class="pagination-css">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="pageNum" :page-sizes="[2, 5, 10, 15]" :page-size="pageSize"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</div>
</el-select>
</el-form-item>
</el-col>
<el-col :span="4">
<el-button size="mini" type="danger" plain @click="del(item)"
style="margin-bottom: 22px; margin-left: 20px">
删除
</el-button>
</el-col>
</el-row>
</div>
</div>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="handleClose('close')">取 消</el-button>
<el-button type="primary" @click="submitHandle">确 定</el-button>
</span>
<!--
1.安装 npm install uuid --save
2.调用
import { v4 as uuidv4 } from 'uuid';
uuidv4();
-->
</div>
</template>
<script>
// import { getUuid } from "@/utils/helper";
import { v4 as getUuid } from 'uuid';
export default {
name: "pageSelect2",
components: {},
props: {
// 默认选中的数据
personList: {
type: Array,
default: () => {
return [];
},
},
taskId: {
type: String,
default: "",
},
},
data() {
return {
form: {
// 人员信息
list: [
{
uuid: getUuid(),
personObj: null,
userId: null,
nickName: null,
userName: null,
deptName: null
},
],
},
rules: {
personObj: [
{
required: true,
message: "人员不能为空",
trigger: ["blur", "change"],
},
],
},
// 模糊查询人员
personData: [
{
userId: 1,
nickName: '张三',
deptId: 1,
deptName: '测试1'
},
{
userId: 2,
nickName: '李四',
deptId: 2,
deptName: '测试2'
},
{
userId: 3,
nickName: '王五',
deptId: 3,
deptName: '测试3'
},
{
userId: 4,
nickName: '赵六',
deptId: 4,
deptName: '测试4'
}, {
userId: 5,
nickName: '小米',
deptId: 5,
deptName: '测试5'
},
{
userId: 6,
nickName: '小明',
deptId: 6,
deptName: '测试6'
},
{
userId: 7,
nickName: '小张',
deptId: 7,
deptName: '测试7'
},
],
total: 0,
pageNum: 1,
pageSize: 1000,
search: "",
};
},
computed: {
},
watch: {
personList: {
handler(val) {
if (val && val != "") {
this.form.list = JSON.parse(JSON.stringify(val));
if (this.form.list && this.form.list != "") {
this.form.list.forEach((item) => {
item.uuid = getUuid();
item.personObj = item;
});
}
} else {
this.form.list = [
{
uuid: getUuid(),
personObj: null,
userId: null,
nickName: null,
userName: null,
deptName: null
},
];
}
},
deep: true,
immediate: true,
},
$route: {
handler() {
this.getPersonList();
},
immediate: true,
deep: true,
},
},
methods: {
// 分页相关
handleSizeChange(val) {
console.log(`每页 ${val} 条`);
this.pageSize = val;
this.getPersonList();
},
handleCurrentChange(val) {
console.log(`当前页: ${val}`);
this.pageNum = val;
this.getPersonList();
},
// 查询人员数据
getPersonList(value) {
//console.log(value,"查询", typeof value);
if (typeof value == "string") {
this.search = value;
}
// listUser({
// pageNum: this.pageNum,
// pageSize: this.pageSize,
// search:this.search,
// }).then((response) => {
// this.personData = response.rows;
// this.total = response.total;
// });
},
//选中,值改变
personChange(data, row) {
this.form.list.forEach((item) => {
if (item.uuid == row.uuid) {
item.userId = data.userId;
item.userName = data.nickName;
item.deptName = data.deptName;
}
});
},
// 添加人员
add() {
this.form.list.push({
uuid: getUuid(),
personObj: null,
userId: null,
nickName: null,
userName: null,
deptName: null
});
},
//编辑-删除人员
del(row) {
this.form.list = this.form.list.filter((ele) => {
return ele.uuid != row.uuid;
});
},
// 取消
handleClose(type = "") {
this.$emit("handleClose", type);
},
// 提交
submitHandle() {
//判断是否重复,重复的话需要去重,给一个提示
let isReturn = this.judgeRepeatHandle(this.form.list);
if (!isReturn) {
let userIds = [];
if (this.form.list) {
this.form.list.forEach((item) => {
if (item.userId) {
userIds.push(item.userId);
}
});
}
console.log(this.form, 'this.form')
console.log(userIds, 'userIds')
this.$refs["form"].validate((valid) => {
if (valid) {
// ......................
}
});
}
},
//判断是否重复,重复的话需要去重,给一个提示
judgeRepeatHandle(list) {
let isReturn = false
console.log(list)
let userIdList = list.map(item => item.userId)
let userIdList2 = [... new Set(userIdList)]
console.log(userIdList, 'userIdList')
console.log(userIdList2, 'userIdList2')
if (userIdList.length != userIdList2.length) {
this.$message("人员不能重复选择!")
isReturn = true
}
return isReturn
},
},
};
</script>
<style scoped>
.person-box {
width: 100%;
display: flex;
flex-direction: column;
}
.add-css {
width: 100%;
display: flex;
justify-content: flex-start;
align-items: center;
}
.dialog-footer {
width: 95%;
display: flex;
justify-content: center;
margin-top: 20px;
}
::v-deep .el-form-item__content {
margin-left: 0px !important;
}
::v-deep .el-row--flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
align-items: center;
justify-content: flex-end;
}
.person-list::-webkit-scrollbar {
display: none;
}
.person-list {
width: 100%;
margin-top: 20px;
max-height: 60vh;
overflow-y: auto;
}
.person-item {
width: 95%;
margin-left: 5%;
box-sizing: border-box;
position: relative;
box-sizing: border-box;
}
.num-box {
position: absolute;
top: 15%;
left: -3%;
}
.pagination-css {
width: 100%;
display: flex;
justify-content: flex-end;
}
</style>
二、效果图