Skip to content

Instantly share code, notes, and snippets.

@sryabov
Created June 20, 2018 20:07
Show Gist options
  • Save sryabov/43b65d4628543c5a5143d4a0e2220835 to your computer and use it in GitHub Desktop.
Save sryabov/43b65d4628543c5a5143d4a0e2220835 to your computer and use it in GitHub Desktop.
vuetify autocomplete component example
<template>
<v-autocomplete
v-model="select"
:loading="loading"
:items="items"
:search-input.sync="search"
no-filter
hide-selected
clearable
return-object
:label="label"
:name="name"
:required="required"
:rules="[v => !this.required || !!v || 'Необходимо выбрать']"
:error="error"
:error-message="errorMessage"
/>
</template>
<script>
import _ from 'lodash';
import Axios from 'axios';
import API_HELICOPTERS from '@/api/helicopters';
export default {
props: {
value: String,
preload: {
type: Array,
default: () => [],
},
error: Object,
errorMessage: Object,
required: {
type: Boolean,
default: false,
},
label: {
type: String,
default: 'Вертолет',
},
name: String,
},
data() {
return {
select: null,
search: null,
items: [],
loading: false,
apiSource: null,
};
},
created() {
this.preloading();
},
watch: {
select(value) {
this.$emit('input', value ? value.value : null);
},
value(value) {
this.setValue(value);
},
search(query) {
if (query && (!this.select || this.select.text !== query)) {
this.querySearch(query);
}
},
},
methods: {
setValue(id) {
if (!id) {
this.select = null;
} else if (!this.select || this.select.value !== id) {
const item = this.getItemById(id);
if (item) {
this.select = item;
} else {
this.preloading();
}
}
},
getItemById(id) {
return this.items.find(item => item.value === id);
},
querySearch: _.debounce(
function querySearch(query) {
this.loading = true;
(this.apiQuery({ value: query }))
.then((response) => {
this.items = _.unionBy(this.items, response, '@id');
})
.finally(() => {
this.loading = false;
})
;
},
500,
),
preloading() {
const preload = this.preload.slice();
if (this.value) {
preload.push(this.value);
}
if (preload.length > 0) {
this.loading = true;
(this.apiQuery({ ids: preload }))
.then((response) => {
this.items = response;
if (this.value) {
const item = this.getItemById(this.value);
if (!item) {
const item404 = {
value: this.value,
text: `[${this.value}]`,
};
this.items.push(item404);
this.select = item404;
} else {
this.select = item;
}
}
})
.finally(() => {
this.loading = false;
})
;
}
},
apiQuery(filters) {
if (this.apiSource) {
this.apiSource.cancel();
}
this.apiSource = Axios.CancelToken.source();
return API_HELICOPTERS.list(
{
filters: { id: filters.ids, boardNumber: filters.value },
properties: ['type', 'boardNumber', 'seats', 'maxDistance', 'maxFlightTime'],
},
{ cancelToken: this.apiSource.token },
).then(data => data.items.map(item => ({
...item,
value: item['@id'],
text: item.boardNumber,
})));
},
},
};
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment