Как в Vue/Vuetify 2.x соединить v-data-table с динамическим v-autocomplete?
Vue.js 2.x / Vuetify 2.x
Нужна динамическая таблица, чтобы на каждой строчке был v-autocomplete. Отслеживание ввода на нужной строке и аякс-запрос, на основании которого будут манипуляции с текущими данными таблицы.
Проблема в отслеживании по полю :search-input.sync="searchText", при такой привязке вводимый запрос повторяется на всех v-autocomplete, если привязать по текущему итерационному элементу :search-input.sync="item.searchText" не получается отслеживать в watch: { searchText(value, oldValue) {} ) }
Подскажите как привязать к уникальной переменной и отследить изменения при вводе? Возможно как-то в watch отследить текущий итерационный объект (туда передаются только старое и новое значение, за исключением объектов с опцией deep: true)?
Очень прошу помочь, гугление не помогает, примеры или старых версий или с той же проблемой. Заранее спасибо.
<div id="app">
<v-app id="inspire">
<v-data-table
:headers="headers"
:items="tableItems"
class="elevation-1"
>
<template v-slot:item.name="{ item }">
<v-autocomplete
v-model="item.searchModel"
:items="items"
:loading="item.isLoading"
:search-input.sync="searchText"
color="black"
hide-selected
hide-no-data
item-text="Description"
item-value="API"
label="Search by Name"
:placeholder="item.name"
return-object
></v-autocomplete>
</template>
</v-data-table>
</v-app>
Vue
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
descriptionLimit: 60,
entries: [],
isLoading: false,
model: null,
searchText: null,
headers: [
{text: 'Dessert name', align: 'start', value: 'name',},
{text: 'Calories', value: 'calories'},
{text: 'Fat (g)', value: 'fat'},
{text: 'Carbs (g)', value: 'carbs'},
{text: 'Protein (g)', value: 'protein'},
{text: 'Iron (%)', value: 'iron'},
],
tableItems: [
{id: 1, searchText: null, searchModel: null, isLoading: false, name: 'Frozen Yogurt', calories: 159, fat: 6.0, carbs: 24, protein: 4.0, iron: '1%',},
{id: 2, searchText: null, searchModel: null, isLoading: false, name: 'Ice cream sandwich', calories: 237, fat: 9.0, carbs: 37, protein: 4.3, iron: '1%',},
{id: 3, searchText: null, searchModel: null, isLoading: false, name: 'Eclair', calories: 262, fat: 16.0, carbs: 23, protein: 6.0, iron: '7%',},
],
}),
watch: {
searchText(val) {
// Items have already been loaded
if (this.items.length > 0) return
if (!val || val === this.selectedName) {
return
}
//this.clearEntries()
this.isLoading = true
this.fetchEntriesDebounced(val)
},
},
computed: {
// Срабатывает при вводе/изменении любого символа
items() {
let result = this.entries.map(entry => {
const Description = entry.Description.length > this.descriptionLimit
? entry.Description.slice(0, this.descriptionLimit) + '...'
: entry.Description
return Object.assign({}, entry, {Description})
})
return result
},
},
methods: {
clearEntries() {
this.count = 0
this.entries = []
},
fetchEntriesDebounced(val) {
clearTimeout(this._searchTimerId)
this._searchTimerId = setTimeout(() => {
this.fetchEntries(val)
}, 2000) /* 1500ms throttle */
},
fetchEntries(val) {
// Lazily load input items
fetch('https://api.publicapis.org/entries')
.then(res => res.json())
.then(res => {
const {count, entries} = res
this.count = count
this.entries = entries
})
.catch(err => {
console.log(err)
})
.finally(() => (this.isLoading = false))
},
},
})
Ответы (1 шт):
Я решил проблему вот так: Параметры передаваемые в компонент, запишите это:
<v-autocomplete
:items="items"
:loading="item.isLoading"
color="black"
hide-selected
hide-no-data
item-text="Description"
item-value="API"
label="Search by Name"
:placeholder="item.name"
return-object
@input.native="handlerInput($event)"
></v-autocomplete>
в методы добавьте это:
handlerInput(event){
this.searchText = event.target.value;
}
С vuetify не работаю, поэтому, возможно, есть более правильное решение