perf: Optimize multiple selections

This commit is contained in:
wangdan-fit2cloud 2025-10-22 11:19:37 +08:00
parent 147eea4160
commit c3fca96c98
13 changed files with 70 additions and 45 deletions

View File

@ -130,6 +130,7 @@
collapse-tags
filterable
clearable
:reserve-keyword="false"
v-model="formValue.default_value"
:teleported="false"
popper-class="default-select"

View File

@ -5,6 +5,7 @@
filterable
allow-create
clearable
:reserve-keyword="false"
v-bind="$attrs"
v-model="_modelValue"
>

View File

@ -48,6 +48,7 @@
filterable
clearable
multiple
:reserve-keyword="false"
collapse-tags
collapse-tags-tooltip
style="width: 220px"

View File

@ -38,7 +38,7 @@
{{ `MCP ${$t('views.tool.title')}` }}
<span class="color-danger">*</span>
</template>
<el-select v-model="form.mcp_tool_ids" filterable multiple>
<el-select v-model="form.mcp_tool_ids" filterable multiple :reserve-keyword="false">
<el-option
v-for="mcpTool in mcpToolSelectOptions"
:key="mcpTool.id"

View File

@ -52,7 +52,7 @@
</el-col>
<el-col :span="1">
<el-button
:disabled="index === 0"
:disabled="tags.length === 1"
link
type="info"
@click="deleteTag(index)"

View File

@ -82,7 +82,7 @@
</el-col>
<el-col :span="1">
<el-button
:disabled="index === 0"
:disabled="tagList.length === 1"
text
@click="deleteTag(index)"
:style="{ marginTop: index === 0 ? '35px' : '5px' }"

View File

@ -47,6 +47,7 @@
<el-select
v-model="form.patterns"
multiple
:reserve-keyword="false"
allow-create
default-first-option
filterable

View File

@ -1,17 +1,34 @@
<template>
<el-dialog :title="$t('views.role.member.add')" v-model="dialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false" :destroy-on-close="true">
<el-form label-position="top" ref="formRef" :rules="rules" :model="form"
require-asterisk-position="right">
<el-dialog
:title="$t('views.role.member.add')"
v-model="dialogVisible"
:close-on-click-modal="false"
:close-on-press-escape="false"
:destroy-on-close="true"
>
<el-form
label-position="top"
ref="formRef"
:rules="rules"
:model="form"
require-asterisk-position="right"
>
<el-form-item :label="$t('views.chatUser.group.usernameOrName')" prop="user">
<el-select v-model="form.user" multiple filterable
:placeholder="$t('common.selectPlaceholder')"
:loading="optionLoading"
:filter-method="filterUser"
<el-select
v-model="form.user"
multiple
filterable
:reserve-keyword="false"
:placeholder="$t('common.selectPlaceholder')"
:loading="optionLoading"
:filter-method="filterUser"
>
<el-option v-for="item in chatUserList" :key="item.id" :label="item.nick_name"
:value="item.id">
<el-option
v-for="item in chatUserList"
:key="item.id"
:label="item.nick_name"
:value="item.id"
>
</el-option>
</el-select>
</el-form-item>
@ -28,22 +45,22 @@
</template>
<script setup lang="ts">
import {ref, reactive, onBeforeMount} from 'vue'
import type {FormInstance} from 'element-plus'
import {MsgSuccess} from '@/utils/message'
import {t} from '@/locales'
import { ref, reactive, onBeforeMount } from 'vue'
import type { FormInstance } from 'element-plus'
import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales'
import SystemGroupApi from '@/api/system/user-group'
import userManageApi from '@/api/system/chat-user'
import type {ChatUserItem} from '@/api/type/systemChatUser'
import {loadPermissionApi} from "@/utils/dynamics-api/permission-api.ts";
import type { ChatUserItem } from '@/api/type/systemChatUser'
import { loadPermissionApi } from '@/utils/dynamics-api/permission-api.ts'
const emit = defineEmits<{
(e: 'refresh'): void;
}>();
(e: 'refresh'): void
}>()
const dialogVisible = ref<boolean>(false)
const defaultForm = {
user: []
user: [],
}
const form = ref<{ user: string[] }>({
...defaultForm,
@ -51,12 +68,12 @@ const form = ref<{ user: string[] }>({
const optionLoading = ref(false)
const chatUserList = ref<ChatUserItem[]>([])
const originalChatUserList = ref<ChatUserItem[]>([]);
const originalChatUserList = ref<ChatUserItem[]>([])
async function getChatUserList() {
try {
const res = await loadPermissionApi('chatUser').getChatUserList(optionLoading)
originalChatUserList.value = res.data;
chatUserList.value = [...res.data];
originalChatUserList.value = res.data
chatUserList.value = [...res.data]
} catch (e) {
console.error(e)
}
@ -64,32 +81,32 @@ async function getChatUserList() {
const filterUser = (query: string) => {
if (!query) {
chatUserList.value = originalChatUserList.value;
return;
chatUserList.value = originalChatUserList.value
return
}
const q = query.toLowerCase();
const q = query.toLowerCase()
chatUserList.value = originalChatUserList.value.filter(
(item) => item.nick_name?.toLowerCase().includes(q) || item.username?.toLowerCase().includes(q)
);
};
(item) => item.nick_name?.toLowerCase().includes(q) || item.username?.toLowerCase().includes(q),
)
}
onBeforeMount(() => {
getChatUserList()
})
const groupId = ref('');
const groupId = ref('')
function open(id: string) {
form.value = {...defaultForm}
form.value = { ...defaultForm }
groupId.value = id
dialogVisible.value = true
}
const formRef = ref<FormInstance>();
const formRef = ref<FormInstance>()
const rules = reactive({
user: [{required: true, message: t('common.selectPlaceholder'), trigger: 'blur'}],
user: [{ required: true, message: t('common.selectPlaceholder'), trigger: 'blur' }],
})
const loading = ref<boolean>(false)
@ -97,14 +114,16 @@ const submit = async (formEl: FormInstance | undefined) => {
if (!formEl) return
await formEl.validate((valid) => {
if (valid) {
loadPermissionApi('userGroup').postAddMember(groupId.value, {"user_ids": form.value.user}, loading).then(() => {
MsgSuccess(t('common.addSuccess'))
emit('refresh')
dialogVisible.value = false
})
loadPermissionApi('userGroup')
.postAddMember(groupId.value, { user_ids: form.value.user }, loading)
.then(() => {
MsgSuccess(t('common.addSuccess'))
emit('refresh')
dialogVisible.value = false
})
}
})
}
defineExpose({open})
defineExpose({ open })
</script>

View File

@ -46,7 +46,7 @@
filterable
style="width: 220px"
>
<el-option v-for="u in type_options" :value="u.value" :label="u.label"/>
<el-option v-for="u in type_options" :key="u.id" :value="u.value" :label="u.label"/>
</el-select>
</div>
</div>

View File

@ -45,7 +45,7 @@
filterable
style="width: 220px"
>
<el-option v-for="u in type_options" :value="u.value" :label="u.label" />
<el-option v-for="u in type_options" :key="u.id" :value="u.value" :label="u.label" />
</el-select>
</div>
</div>

View File

@ -45,7 +45,7 @@
filterable
style="width: 220px"
>
<el-option v-for="u in type_options" :value="u.value" :label="u.label"/>
<el-option v-for="u in type_options" :key="u.id" :value="u.value" :label="u.label"/>
</el-select>
</div>
</div>

View File

@ -39,6 +39,7 @@
filterable
clearable
multiple
:reserve-keyword="false"
collapse-tags
collapse-tags-tooltip
style="width: 220px"

View File

@ -22,6 +22,7 @@
"
filterable
multiple
:reserve-keyword="false"
style="width: 100%"
collapse-tags
collapse-tags-tooltip