我在 vuetify 领域相对较新,在我的第一个 Web 应用程序开发过程中,我在事件处理方面遇到了很多困难。 在本例中,我正在使用 VAutocomplete 编写一个“UserPicker”组件。
该组件的工作原理是向服务器发送异步请求,服务器响应与用户输入匹配的帐户列表。
结果应该与此处的示例非常相似: https://vuetifyjs.com/en/components/autocompletes/#slots
一切似乎都工作正常,除了我还没有找到一种方法来捕捉这个问题的主题中的事件。
这是我写的代码:
<script setup lang="ts">
import { ref, watch } from "vue";
import { useServerRequestsStore } from "@/stores/server-requests";
const input = ref();
const items = ref<Array<UserPreview>>([]);
const select = ref<Array<UserPreview>>([]);
const selectSet = new Set();
const search = ref("");
const serverRequests = useServerRequestsStore();
interface UserPreview {
firstName: string;
lastName: string;
username: string;
avatar: string;
}
function addUser(userItem: UserPreview) {
try {
selectSet.add(userItem.username);
select.value.push(userItem);
items.value = [];
search.value = "";
input.value.focus();
} catch (error) {
console.log(error);
}
}
function removeUser(userItem: UserPreview) {
selectSet.delete(userItem.username);
const toRemove = select.value.findIndex(
(added) => added.username == userItem.username
);
console.log("removing " + userItem.username + " at index " + toRemove);
select.value.splice(toRemove, 1);
console.log("after removal:", select.value);
}
watch(search, async (val) => {
if (val.length == 0) return;
try {
const users = await serverRequests.getUserByUsername(val, false);
items.value = users
.filter((user: any) => !selectSet.has(user.userInfo.username))
.map((user: any) => ({
firstName: user.userInfo.firstName,
lastName: user.userInfo.lastName,
username: user.userInfo.username,
title: user.userInfo.username, //richiesto per far comparire automaticamente i suggerimenti
avatar: user.userInfo.profilePicture,
}));
} catch (error) {
items.value = [];
}
});
</script>
<template>
<VAutocomplete
@keydown.enter.prevent
ref="input"
v-model="select"
v-model:search="search"
:items="items"
class="mx-4"
density="compact"
hide-no-data
hide-details
label="Seleziona destinatari"
style="max-width: 300px"
chips
closable-chips
multiple
>
<template v-slot:item="{ item }"
><VListItem class="text-center" @click="addUser(item.raw)">
<VAvatar size="40px" color="black" variant="outlined"
><VImg alt="profile avatar" :src="item.raw.avatar" />
</VAvatar>
<VListItemTitle
>{{ item.raw.firstName }} {{ item.raw.lastName }}</VListItemTitle
>
<VListItemSubtitle>{{ item.raw.username }}</VListItemSubtitle>
</VListItem>
</template>
<template v-slot:chip="{ item }">
<VChip
@click:close="removeUser(item.raw)"
:text="item.raw.username"
></VChip>
</template>
</VAutocomplete>
</template>
正如您在模板底部看到的使用 VChip 组件的地方,我能够正确处理 @click:close 事件,但是 VChip(至少在这种情况下)也可以通过选择它们来关闭在编辑 VAutocomplete 输入时使用箭头键并按退格键。
我尝试过使用各种 @vnode-before-unmount、@keydown.backspace 和 @update:model-value 事件,但没有一个成功。 需要注意的一个具体细节是,与其他 2 个事件不同,@vnode-before-unmount 实际上被正确触发,并正确调用了removeUser 函数,但是,由于某种原因,组件的范围没有继续到过程中,事实上,当通过此事件调用处理程序时,选择引用为空,而当用户触发 @click:close 时,它会正确填充。
提前感谢您的回答。
github上有一个解决方案,我希望它可以帮助也遇到这个问题的人,我只是将
@click.stop
更改为@click.close
:https://github.com/vuetifyjs/vuetify/issues/16740