Imagine having a Vue3 app with a store where the state is structured like this:
const store = {
state () => ({
items: []
}),
// ...
}
Within the App.vue file, there is only a single <router-view />
as the template content.
Additionally, there exists an ItemList.vue
view with the following structure:
<template>
<div v-if="!loading">
<Item
v-for="item in items"
:key="item.id"
:item="item"
></Item>
</div>
<Skeleton v-else />
</template>
<script>
import Item from "...";
import Skeleton from "..."
import { mapState } from "vuex";
export default defineComponent({
name: "CourseList",
mixins: [loadingMixin],
components: {
Item, Skeleton
},
async created() {
this.loading = true
this.$store.dispatch("getItems", {
categoryId: this.$route.params.categoryId
})
this.loading = false
...
});
</script>
The functionality of the app allows users to visit URLs such as categories/<id>/items
and access items specific to that category. A flat array stores the viewed items within the store's state. Whenever the ItemList
component is initialized, an action triggers an API call to retrieve new items for display. In the meantime, a loading skeleton is presented to the user for visual feedback.
An issue arises when navigating back to the same category view as previous visits may still trigger a re-fetching of items, resulting in unnecessary delays if the data has not been updated. The challenge lies in displaying existing data without waiting for a refresh while maintaining the ability to fetch new content when necessary.
Is it possible to achieve this behavior in Vue? Attempts using the <keep-alive>
component and assigning a :key
based on the route's category ID parameter have proven ineffective so far.