Currently, I am implementing a parent companyList
component along with a reusable Table
component and an useFetch
composable in vue 3.2.
Prior to integrating the Table
component, my code looked like this:
companyList
<script setup>
import { computed } from 'vue';
import useFetch from '@/composables/useFetch';
import { formatEmail, formatPhone, formatEnterpriseNumber } from '@/utils/formatters';
const { response, isFetching, error } = useFetch('get', '/companies');
const companies = computed(() =>
response.value?.companies?.map((company) => ({
id: `#${company.id}`,
name: `${company.legal_entity_type} ${company.business_name}`,
enterprise_number: formatEnterpriseNumber(company.enterprise_number),
email: formatEmail(company.email),
phone: formatPhone(company.phone),
}))
);
</script>
Within the Table
component that includes pagination, sorting, and search functionality, a watchEffect observes state changes and triggers an emit from the parent component, specifically getCompanies
. Here's how it looks:
companyList
<script setup>
const getCompanies = (search, sortKey, orderKey) => {
const { response, isFetching, error } = useFetch('get', '/companies', {
params: {
keyword: search,
sort_by: sortKey,
order_by: orderKey,
},
});
};
const companies = computed(() =>
response.value?.companies?.map((company) => ({
id: `#${company.id}`,
name: `${company.legal_entity_type} ${company.business_name}`,
enterprise_number: formatEnterpriseNumber(company.enterprise_number),
email: formatEmail(company.email),
phone: formatPhone(company.phone),
}))
);
</script>
<template>
<Spinner v-if="isFetching" size="medium" />
<ErrorMessage v-else-if="error" showReload :description="error" />
<NoDataMessage v-else-if="!companies || companies.length <= 0" />
<div v-else>
<Table :columns="tableColumns" :data="companies" @fetchData="getCompanies">
<template v-slot:id="{ item }">
<Badge>
{{ item.id }}
</Badge>
</template>
<template v-slot:actions="{ item }">
<router-link :to="{ name: 'clientDetails', params: { client_id: item.id } }" class="text-blue-500 lowercase"> {{ $tc('detail', 2) }} </router-link>
</template>
</Table>
</div>
</template>
Question: I am looking for a way to extract the response
, isFetching
, and error
values from the getCompanies function and utilize them inside the template tags without resorting to defining refs
to retrieve them. Additionally, using different variable names makes the solution less optimal. Is there an alternative approach to the following workaround:
const local_response = ref(null);
const local_isFetching = ref(null);
const local_error = ref(null);
const getCompanies = (search, sortKey, orderKey) => {
const { response, isFetching, error } = useFetch('get', '/companies', {
params: {
keyword: search,
sort_by: sortKey,
order_by: orderKey,
},
});
local_response.value = response;
local_isFetching.value = isFetching;
local_error.value = error;
};
const companies = computed(() =>
local_response.value?.companies?.map((company) => ({
id: `#${company.id}`,
name: `${company.legal_entity_type} ${company.business_name}`,
enterprise_number: formatEnterpriseNumber(company.enterprise_number),
email: formatEmail(company.email),
phone: formatPhone(company.phone),
}))
);