Situation: An analysis module on a website that needs to display three different data tables, one at a time.
Approach: The module is a component containing three buttons. Each button sets a variable which determines which table to render. Depending on the variable value, the table calls an API for specific information.
The structure is as follows:
analysis component:
<template>
<div class="buttons">
<div @click="setAnalysisSection('POSITIONS')">POSITIONS</div>
<div @click="setAnalysisSection('RESULTS')">RESULS</div>
<div @click="setAnalysisSection('FIXTURE')"">FIXTURE</div>
</div>
<data-table v-if="activeAnalysis === 'FIXTURE'" data="fixture" environment="view" :loading="loading"></data-table>
<data-table v-if="activeAnalysis === 'RESULTS'" data="results" environment="view"></data-table>
<data-table v-if="activeAnalysis === 'POSITIONS'" data="positions" environment="view"></data-table>
</template>
<script>
import dataTable from '@/components/Table.vue';
export default {
components: {
'data-table' : dataTable,
},
data() {
return {
activeAnalysis: 'RESULTS',
}
},
methods: {
setAnalysisSection(section) {
this.activeAnalysis = section;
}
},
}
</script>
table component:
<template>
<div>
<table class="table__fixture">
<thead>
<tr>
<td>DATE</td>
<td>TIME</td>
<td>CONFIRMATION</td>
</tr>
</thead>
<tbody>
<tr v-if="tableData.data" v-for="row in tableData.data" :key="row.id">
<td>{{row.date | date}}</td>
<td>{{row.time | time}}</td>
<td>{{row.zone}}</td>
</tr>
</tbody>
</table>
<table class="table__postions">
<thead>
<tr>
<td>POSITION</td>
<td>PTS</td>
<td>PLAYED</td>
</tr>
</thead>
<tbody>
<tr v-if="tableData.data" v-for="row in tableData.data" :key="row.id">
<td>{{row.position}}</td>
<td>{{row.points}}</td>
<td>{{row.played}}</td>
</tr>
</tbody>
</table>
<table class="table__results">
<thead>
<tr>
<td>DATE</td>
<td>TIME</td>
<td>CONFIRMATION</td>
</tr>
</thead>
<tbody>
<tr v-if="tableData.data" v-for="row in tableData.data" :key="row.id">
<td>{{row.date | date}}</td>
<td>{{row.time | time}}</td>
<td>{{row.zone}}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script>
import axios from 'axios';
export default {
props: ['data', 'environment'],
data() {
return {
tableData: '',
};
},
mounted() {
if (this.data === 'fixture' && this.environment === 'view') {
this.fetch('fixture', 1, 15);
} else if (this.data === 'positions') {
this.fetch('positions', 1, 100);
} else if (this.data === 'results') {
this.fetch('results', 1, 15);
}
},
methods: {
async fetch(data, page, perPage) {
console.log('Fetching data!');
const self = this
if (data === 'fixture') {
try {
const response = await axios.get(`apilinkhere/public/fixture?page=${page}&per_page=${perPage}`);
self.tableData = response.data;
} catch (error) {
throw new Error(error);
}
} else if (data === 'positions') {
try {
const response = await axios.get(`apilinkhere/positions?page=${page}&per_page=${perPage}`);
self.tableData = response.data;
} catch (error) {
throw new Error(error);
}
} else if (data === 'results') {
try {
const response = await axios.get(`apilinkhere/public/results?page=${page}&per_page=${perPage}`);
self.tableData = response.data;
} catch (error) {
throw new Error(error);
}
}
},
},
};
</script>
Issue:
The problem lies in the fact that the mounted hook only executes once during the initial rendering of the component, not upon each subsequent render (such as when changing the activeAnalysis). Alternatively, utilizing the Updated hook for calling the API method for different table data, as suggested in the documentation, results in an infinite loop of method calls.
According to Vue's documentation, watching a variable could solve this issue. However, it may be unclear where and how to implement this watch functionality.
NOTE:
You might notice discrepancies in the provided code (filters applied to variables in the template that are not defined in the script, for instance). This was done to enhance readability by cleaning up the copied code. Any language inconsistencies are due to the original code being partially written in Spanish and do not affect the core problem or necessary information for providing a solution.