#vue.js #vuetify.js #v-autocomplete
#vue.js #vuetify.js #v-автозаполнение
Вопрос:
У меня есть автозаполнение 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-автозаполнение. Первый вызов на сервер выполняется для первых 20 футболистов.
- Пользователь начинает вводить строку. Новый вызов выполняется на сервер со строкой в качестве параметра и возвращаются новые результаты.
- Пользователь выбирает некоторых футболистов из результата.
- Пользователь вводит какую-то новую строку и так далее.
Что происходит сейчас? Когда пользователь вводит новый поиск, фишки из предыдущего выбора немедленно исчезают. Если он выбирает чип из нового списка предложений, чип отображается во входных данных, пока не будет выполнен новый поиск, а затем чип исчезает. Это объясняется тем фактом, что чипы не включены в предложения. Я нашел обходной путь, который заключается в том, чтобы всегда нажимать на уже существующий выбор в предложениях, но это некрасиво, и это не то, чего ожидает пользователь.
Я рассматривал возможность использования combobox вместо этого, но я не уверен, решит ли это мою проблему.
Комментарии:
1. Сейчас натыкаюсь на ту же проблему. Любое слово о том, в чем может быть проблема?
2. @AaronMeier, нет, понятия не имею.
3. Я решил использовать v-combobox, и это решило проблему для меня.