I have a "ProjectsSearchBar" component for searching and selecting projects that are making calls to API to fetch projects. I am trying to place two same components side by side. Unfortunately, only one of them is loading data, the other kind of resets? In short, it loads endlessly. If i delete second component, it works normally. It's like they're overwriting each other. In addition, when I log the query result of both components to the console, it turns out that only one pops up. I looked at various threads, but the only answer I found was that for both components you have to give :key. I did, it didn't work. I also gave a key to an element in the component. It didn't work either. If you have any idea, I'd be grateful.
That's how it looks:
<ProjectsSearchBar
key="component1"
v-model="mergeProject"
:multiple="false"
:clearable="true"
label="Wybierz projekt główny"
/>
<ProjectsSearchBar
key="component2"
v-model="absorbedProjects"
:multiple="true"
:clearable="true"
label="Wybierz projekty wchłaniane"
/>
ProjectsSearchBar code:
<template>
<v-autocomplete
:value="value"
:items="projectsItems"
:loading="isLoadingData"
:search-input.sync="searchProject"
outlined
:clearable="clearable"
:chips="multiple"
:small-chips="multiple"
deletable-chips
item-text="name"
:item-value="getValueWrapper"
:label="label"
placeholder="Wpisz by wyszkać"
:multiple="multiple"
@input="handleInput"
@change="$emit('change', value)"
>
<template #item="data">
<template v-if="typeof data.item !== 'object'">
<v-list-item-content v-text="data.item" />
</template>
<template v-else>
<v-list-item-content>
<v-list-item-title v-html="data.item.name" />
<v-list-item-subtitle v-if="data.item.client">
{{ data.item.client.name }}
</v-list-item-subtitle>
<v-list-item-subtitle v-if="data.item.job_types">
{{ itemHourlyRate(data.item.job_types) }}
</v-list-item-subtitle>
</v-list-item-content>
</template>
</template>
</v-autocomplete>
</template>
<script>
export default {
name: 'ProjectsSearchBar',
props: {
value: {
// some props
},
},
data: () => ({
selected: [],
searchProject: '',
isLoadingData: true,
projects: [],
}),
computed: {
user: get('auth/user'),
currentPartyId: get('global/currentPartyId'),
projectsItems() {
let currentItems = [];
if (this.value !== null) {
currentItems = Array.isArray(this.value) ? this.value : [this.value];
} else {
currentItems = [];
}
const current = currentItems.map((el) => el.id);
const projects = this.projects.filter((el) => !current.includes(el.id));
return [...currentItems, ...projects];
},
itemHourlyRate() {
return (jobTypes) => {
if (jobTypes && this.selectedJobType) {
const selectedType = jobTypes.find((type) => type.id === this.selectedJobType.id);
if (selectedType) {
return `Stawka dla wybranego typu pracy: ${selectedType.pivot.hourly_rate} zł/h`;
}
}
return '';
};
},
},
watch: {
searchProject() {
this.searchDebounce();
},
clientIds() {
this.searchDebounce();
},
},
methods: {
searchDebounce: debounce(function () {
this.fetchProjects();
}, 300),
handleInput(e) {
this.$emit('input', e);
this.searchProject = '';
},
getValueWrapper(el) {
return el;
},
async fetchProjects() {
this.isLoadingData = true;
try {
const result = await this.$API.projects.getProjects(
this.currentPartyId,
{
page: 1,
limit: 20,
project_name: this.searchProject,
client_id: this.clientIds,
status: this.statuses,
},
);
this.projects = result.data.data;
this.$emit('projects-loaded', this.projects);
} catch (e) {
// eslint-disable-next-line no-console
console.error(e);
} finally {
this.isLoadingData = false;
}
},
},
};
</script>
Thanks for any advice. If you need anything else, let me know. I am using Vue 2.0