VUE - 搜索多選下拉框組件
Max.Bai
2020-04
記錄一個多選搜索下拉框組件
功能:
1. 支持搜索,
2. 多選,
3. 重新搜索依舊保留已選的選項
ElementUI 組件文檔 https://element.eleme.cn/2.12/#/zh-CN/component/select
效果
源碼:
<template>
<el-select
v-model="localUserIDs"
multiple
filterable
size="small"
:placeholder="placeholder"
class="text-select-hidden"
style="width:100%;height:33px;"
:loading="loading"
:multiple-limit="15"
remote
:remote-method="remoteSearchUser"
>
<el-option
v-for="item in localUserOptions"
:key="item.value"
:label="item.label"
:value="item.value"
:disabled="item.disabled"
>
<span style="float: left">{{ item.label }}</span>
<span
style="float: right; color: #8492a6; font-size: 13px;padding-right:20px;"
>{{ item.dept_path_names }}</span>
</el-option>
</el-select>
</template>
<script>
// 遠程搜索接口 返回 {"value":123, label:"max.bai", "dept_path_names": "集團/技術"}
import { baseusername } from "@/api/base";
export default {
name: "userSelecte",
props: {
userIds: {
// 已選的值
type: Array,
default() {
return [];
}
},
userNames: {
// 已選的文本
type: Array,
default() {
return [];
}
},
userOptions: {
// 默認選項 可以沒有
type: Array,
default() {
return [];
}
}
},
data() {
return {
placeholder: "請輸入姓名搜索",
loading: false,
localUserIDs: this.userIds, // selected value list
localUserNames: this.userNames, // selected label list
localUserOptions: this.userOptions, // select options
selectedUserOptions: [] // 已選用戶選項 selected options
};
},
mounted: function() {
this.loadUsers(true);
},
watch: {
// 觀察選擇值,變化更新 selected options,同時更新父組件值
localUserIDs: {
deep: true,
handler: "refreshSelectedUser"
}
},
methods: {
async loadUsers(init) {
// 首次加載,查詢已選用戶,添加到選項中,添加默認選項,添加提示
if (this.localUserIDs.length > 0) {
this.loading = true;
const { data } = await baseusername({ usernames: this.localUserIDs });
this.selectedUserOptions = data;
if (init) {
this.localUserOptions = this.selectedUserOptions
.concat(this.userOptions)
.concat([
{
value: "-1",
label: this.placeholder,
disabled: true
}
]);
}
this.loading = false;
}
},
refreshSelectedUser() {
// 刷新已選用戶
if (this.localUserIDs.length > 0) {
// update selected options
this.selectedUserOptions = [];
for (let j = 0; j < this.localUserOptions.length; j++) {
if (this.localUserIDs.includes(this.localUserOptions[j].value)) {
this.selectedUserOptions.push(this.localUserOptions[j]);
}
if (this.selectedUserOptions.length >= this.localUserIDs.length) {
break
}
}
} else {
this.selectedUserOptions = [];
}
this.updateParentData();
},
updateParentData() {
// 更新父組件value
this.$emit("update:userIds", this.localUserIDs);
// 更新父組件label
this.localUserNames = [];
for (let i = 0; i < this.selectedUserOptions.length; i++) {
this.localUserNames.push(this.selectedUserOptions[i].label);
}
this.$emit("update:userNames", this.localUserNames);
},
async remoteSearchUser(query) {
// 遠程搜索
if (query !== "") {
this.loading = true;
const { data } = await baseusername({ name: query });
// 更新選項,添加已選擇選項
this.localUserOptions = JSON.parse(
JSON.stringify(this.selectedUserOptions)
);
// 更新選項,添加不包含已選的選項
for (let i = 0; i < data.length; i++) {
let find = false;
for (let j = 0; j < this.selectedUserOptions.length; j++) {
if (data[i].value == this.selectedUserOptions[j].value) {
find = true;
break;
}
}
if (!find) {
this.localUserOptions.push(data[i]);
}
}
this.loading = false;
}
}
}
};
</script>
<style>
</style>