我有一个 Vuetify 自动完成功能,带有多个选择的芯片,其建议下拉菜单未存储在本地,但当用户开始在输入字段中输入时,总是从服务器异步检索。代码看起来像这样:
fetch("/echo/html/", {
method: "POST",
headers: {
"Content-Type": "application/json; charset=utf-8"
},
body: "html=<a href='#'>hello world</a>"
})
.then((response) => response.rows = [{
id: "6rfsda",
name: "Cristiano Ronaldo",
club: "Juventus FC"
},
{
id: "vfgfas",
name: "Lionel Messi",
club: "FC Barcelona"
},
{
id: "fgfaex",
name: "Mohammd Salah",
club: "Liverpool FC"
}
])
.catch((error) => {
console.error(error)
})
var vm = new Vue({
el: "#app",
data() {
return {
selectedFootballPlayers: [],
footballPlayers: [],
footballPlayerSearch: {
loading: false,
search: ''
}
}
},
watch: {
'footballPlayer.search': function watch(val) {
this.queryFootballPlayers(val);
},
selectedFootballPlayers() {
this.footballPlayerSearch.search = '';
},
},
methods: {
async queryFootballPlayers(val) {
this.footballPlayerSearch.loading = true;
this.footballPlayers = [];
if (this.selectedFootballPlayers.length > 0) {
this.selectedFootballPlayers.forEach((player) => this.footballPlayers.push(player));
}
let response;
try {
const result = apiUrl.findFootballPlayers({
query: val
}); //I tried to get the async simulation call to work, but I have no clue how
response = await result.response;
} catch (err) {
console.log('There was an error');
}
this.footballPlayerSearch.loading = false;
},
remove(item) {
const itemIndex = this.selectedFootballPlayers.findIndex((el) => el.id === item.id);
this.selectedFootballPlayers.splice(itemIndex, 1);
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@5.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@1.x/dist/vuetify.min.css" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Material+Icons' rel="stylesheet" type="text/css">
<div id="app">
<v-app light>
<v-autocomplete v-model="selectedFootballPlayers" :items="footballPlayers" label="Favorite Footbal Players" :loading="footballPlayerSearch.loading" :no-data-text="'No football players were found'" :search-input.sync="footballPlayerSearch.search" item-text="name"
return-object no-filter multiple style="width: 100%">
<template v-slot:selection="data">
<v-chip
v-bind="data.attrs"
:input-value="data.selected"
>
<span>{{ data.item.name }}</span>
<v-icon
right
size="18"
@click="remove(data.item)"
>
close
</v-icon>
</v-chip>
</template>
<template slot="item" slot-scope="{ item }">
<v-list-tile-content>
<div class="d-flex align-center justify-center">
<v-checkbox
v-model="item.selected"
:ripple="false"
:label="item.name"
multiple
/>
{{ item.name }}
</div>
</v-list-tile-content>
</template>
</v-autocomplete>
</v-app>
</div>
(不幸的是,我无法让代码在 JSFiddle 中运行,因为我不知道如何在那里模拟异步调用。)
流程如下:
- 用户关注 v-autocomplete 字段。对前 20 名足球运动员进行第一次调用服务器。
- 用户开始键入字符串。使用字符串作为参数对服务器进行新调用,并返回新结果。
- 用户从结果中选择一些足球运动员。
- 用户键入一些新字符串,等等。
现在会发生什么?当用户键入新的搜索时,先前选择的筹码会立即消失。如果他从新的建议列表中选择一个筹码,则该筹码会显示在输入中,直到进行新的搜索,然后该筹码就会消失。这可以通过芯片不包含在建议中的事实来解释。我发现了一个关于它的技巧,即总是在建议中推送预先存在的选择,但这很丑陋,而且这不是用户所期望的。
我考虑改用组合框,但我不确定这是否能解决我的问题。